Unlock seamless workflows and faster delivery with our latest releases - Join the deep dive

Tips for working with historical data in Sanity and how to sanitize user input

17 replies
Last updated: May 20, 2021
Anyone here worked with historical data in Sanity? We want to give our users a way to navigate historical versions of our pages, so the plan is to use the history-api to do some clever queries and display a dropdown menu where the users can select different revisions of the page. If anyone has done something similar I would greatly appreciate some tips and pointers 🙂 For example it doesn't seem like it possible to use the history-api from the
@sanity/client
?
May 6, 2021, 7:49 AM
Hi Daniel! You’re right that our js-client don’t have support for the history API. This is how the Studio are fetching the history https://github.com/sanity-io/sanity/blob/next/packages/@sanity/desk-tool/src/panes/documentPane/documentHistory/history/controller.ts#L256
May 6, 2021, 8:16 AM
Thanks
user P
, thats very helpfull 🙌
May 6, 2021, 8:32 AM
No problem 🙂
May 6, 2021, 8:33 AM
We've built a solution where our end users can browse document history, and it works really nicely thanks to the history-api 🎉
Right now we are fetching document-history server-side (nextjs) using urls built like this: ``https://${projectId}.
apicdn.sanity.io/v1/data/history/${dataset}/documents/${docId}?time=${time} `` .
time
and
docId
is taken directly from the request-url (for example
<http://localhost:3000/historikk/0caeeb00-deb0-4310-bb04-17ffb2ccd165/2021-05-12T12:09:23.000Z>
). Does this leave us open to some kind of vulnerability? Should we for example sanitise this input, validate it, cache it, or worry about ddos attacks etc..? Other things we should consider?
Thankful for any input on this
🙂
Code here:

https://github.com/navikt/dp-faktasider-frontend/blob/08795ca914ae4f649c419b04e14bc832e9b1f5a1/src/pages/historikk/%5B...slug%5D.tsx#L34
https://github.com/navikt/dp-faktasider-frontend/blob/08795ca914ae4f649c419b04e14bc832e9b1f5a1/src/components/historikk/api/historikkFetcher.ts#L18
https://github.com/navikt/dp-faktasider-frontend/blob/08795ca914ae4f649c419b04e14bc832e9b1f5a1/src/components/historikk/api/revisionsFetcher.ts#L16
May 19, 2021, 11:53 AM
Hi
user Q
!
I would always sanitise user input. If you’re taking the docId and time directly without sanitising it it might leave you vulnerable to path traversal attacks. Without having looked to much on the code, and I assume the
historikkFetcher
is using a client/token with elevated privileges, it could be possible to construct a query that fetches a document you shouldn’t have access to
May 19, 2021, 3:40 PM
Thanks
user P
🙂
I'm new to sanitising user input, what is the correct way to do this? Any libraries/javascript functionality that can sanitise this in a meaningful way? Or checking the id with a regex like
/[^a-z0-9-]/.test(docId)
and time with another suitable regex?
Any other threats we should consider? By allowing any time as input, are we more vulnerable against ddos-attacks for example?
May 20, 2021, 8:29 AM
Any suggestion as to how we should sanitise these inputs? Any libraries that can sanitise this in a meaningful way? Or checking the id with a regex like
/[^a-z0-9-]/.test(docId)
and time with another suitable regex?
Any other threats we should consider? By allowing any time as input, are we more vulnerable against ddos-attacks for example?
May 20, 2021, 8:29 AM
What does your IDs look like? 🙂
May 20, 2021, 11:21 AM
What does your IDs look like? 🙂
May 20, 2021, 11:21 AM
For time you can use
date-fns
to validate date times 🙂
May 20, 2021, 11:21 AM
/[^a-z0-9-]/.test(docId)
will match everything that isn’t:
a-z
,
0-9
or
-
, I assume you maybe meant without the negative op(
^
) ?
May 20, 2021, 11:22 AM
These are Sanity-document IDs, so I thought I'd test if they used some illegal characters and in that case throw an error or something 🙂 But would maybe a simple
encodeURIComponent(id/time)
do the trick?
May 20, 2021, 11:28 AM
Right! The id’s generated by the studio are uuids,
const uuidMatcher = /^[a-z0-9]+-[a-z0-9]+-[a-z0-9]+-[a-z0-9]+-[a-z0-9]+$/
would return true on a valid id
May 20, 2021, 11:33 AM
with
encodeURIComponent
you should decode on receiving end, it’s not for sanitising input in that way.ie,
encodeURIComponent("+") => %2B
so if the
time
field contains a plus it won’t be valid when you pass it to the api client 🙂
May 20, 2021, 11:35 AM
with
encodeURIComponent
you should decode on receiving end, it’s not for sanitising input in that way.ie,
encodeURIComponent("+") => %2B
so if the
time
field contains a plus it won’t be valid when you pass it to the api client 🙂
May 20, 2021, 11:35 AM
https://date-fns.org/v2.21.3/docs/isValid Can be used for validating the time field, or you can do
function isValidDate(time) { try { new Date(time); return true } catch(err) { return false; }}
May 20, 2021, 11:40 AM
Perfect, thank you 🙂 🙌
May 20, 2021, 11:41 AM

Sanity– build remarkable experiences at scale

Sanity is a modern headless CMS that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.

Was this answer helpful?