TL;DR: A two-year retrospective on spending my COVID quarantine accidentally discovering a bevy of personally identifiable information published on the Internet due to someone forgetting to read the fine manual. 1
Overview
I acquired COVID-19 in the fall of 2022 which was bad for two reasons: 1) I had COVID-19 and 2) I needed a project to kill five days of isolation. Text messages from my state’s health department were just the ticket to find a fun little project and identify that customers of one of the world’s largest online survey company weren’t heeding warnings given in the fine manual.
This post explores what was behind those text messages, particularly focuses on the structure used for short URLs within them for reasons that will become apparent, and then details the information provided behind each of the URLs. Ultimately, this post highlights why it is important that customers read the fine manual of any service they purchase and why care should be taken to construct short URLs wisely. The underlying issues were reported and mitigated.
The vast majority of this post was written in late 2022 when the events occurred, however I opted to hold off on publishing to ensure the issues presented herein were not abused. Changes to the services mentioned over the past two years may render current examples slightly different from what was seen then (which is a good thing!) and the core issues at hand were mitigated long ago.
Text Messages
This journey started in October 2022 at the start of my bout with COVID when my phone woke me up from a fevered nap, telling me I had a new text message. Two subsequent text messages also interrupted my sleep, but the short URLs present in all three of them woke my brain up enough to do a little statistical analysis of how well they were constructed and what lay behind them.
Boring Text Message
The first text message from CVS notified me that my COVID results were available. Unshockingly based on my symptoms, I was positive. It contained a link that was hosted on the domain owned and operated by CVS which made it easy to verify it was not a phishing attempt. CVS creates its text message short URLs using a sub-domain of its normal website and an 8-character alphanumeric code. Eight characters provides CVS an address space of roughly 218 trillion unique possibilities, it could text everyone in the world each day for 79 years and not run out of new URLs.
By way of example, the link appeared like: https://i.cvs.com/1A2b3C4d
Upon visiting the link, CVS’s website forced me to authenticate with my date of birth prior to providing my test results. Nothing in the web page’s source code seemed particularly noteworthy and there was no way around authenticating myself with my date of birth. This is a positive example of how a website should behave: an obviously not malicious domain with no obvious ways to bypass authentication or leak information.
Interesting Text Messages
Exposure Notification Express
The first interesting link I received via text message belonged to Google and Apple’s Exposure Notifications Express (EN Express) program in a text that led off by stating it was my state’s health department, but did not point back to my state’s health department domain. As someone who hadn’t kept up to date on the contact tracing technology, it looked a bit phishy, especially since the domain was just registered in 2020. However, googling for the domain it was pointing to (en.express) turned up the EN Express program and its ties to Google and Apple which mollified my concerns. EN Express used a 16-character alphanumeric identifier in the URL to point the user at the unique page for them. While it “only” used lowercase characters and digits, a “mere” 36 choices for each character, by using 16 characters in the string EN Express gave itself 7.9 septillion possibilities.
By way of example, the link appeared like: https://us-aa.en.express/v?c=abcdefgh12345678
Once clicked, the website redirected to the exposure notification link and there was nothing interesting left to poke at. While the domain could have been slightly less phishy such as by allowing a redirect from a subdomain on the state’s health department website, there was no way to abuse the website, so it is still a moderately positive example.
Qualtrics Contact Tracing Survey (Initial)
About 30 minutes later, I received a second interesting link from the same phone number that sent the EN Express message. It used different wording to also claim to be from my state’s health department and it included a link to a different link-shortening domain on the Turks and Caicos Islands TLD (.tc) which seemed phishy since I don’t live particularly close to the West Indies. However, it turned out to be the link-shortening domain used by survey company Qualtrics and that my state was using a Qualtrics survey form to augment manual call centers. Qualtrics used a one-character folder under the root of the domain and then an 8-character alphanumeric code for its short URLs. Assuming all links are under the same folder, this provides the same number of possibilities as CVS’s link.
By way of example, the link appeared like: https://ql.tc/b/1A2b3C4d
This shortened URL was a 301 redirect to a survey page on the company’s main domain. Once followed, the full URL appeared like: https://aa.qualtrics.com/jfe/form/SV_AAAAAAAAAAAAAAA?Q_DL=SMSD_BBBBBBBBBBBBBBB_AAAAAAAAAAAAAAA_CGC_CCCCCCCCCCCCCCC&Q_CHL=DDDDD
The length of the survey URL makes it obvious why a shortened URL was used and it appeared to encode information about the survey itself, specifically:
- The survey being answered, a 15-character alphanumeric ID (
AAAAAAAAAAAAAAA
), which is the unique identifier for this specific survey. - The Distribution ID, a 15-character alphanumeric ID (
BBBBBBBBBBBBBBB
), which is the unique identifier for the distribution used to reach the respondent. - The Panel Member ID, a 15-character alphanumeric ID (
CCCCCCCCCCCCCCC
), which is the unique identifier for the particular respondent. - The channel categorization, which is a string describing how the respondant was reached (
DDDDD
)
What intrigued me about this link was how much of this URL appeared to be static. Anyone else that received the survey knew 30 of the 60 random characters in it, since the survey form (AAAAAAAAAAAAAAA
in our example) is both the page to request and embedded in the distribution list. Of the remaining 30 random characters, 15 are the unique panel member ID for the respondent and 15 are the distribution ID. The distribution ID can have many people in it and a survey can have many distributions associated with it. That leaves the panel member ID as the real entropy in the URL. If there was a way to correlate panel member IDs to surveys and distribution IDs then there would be no entropy, which would be a problem if the URL itself provided access to sensitive information (foreshadowing).
Qualtrics Contact Tracing Survey (Reminder)
The next morning, I woke up to another text from the contact tracing survey since I hadn’t yet finished the survey. This link was on the same Qualtrics link-shortening domain as the one the previous day, but now it had no folder and was only 6 characters. Six alphanumeric characters provide roughly 57 billion unique possibilities. That sounds like a lot, but not compared to the other services we have been looking at. If this service sent texts to everyone on the planet each day (such as during a global pandemic), it would only last seven days. That’s 4,100 times shorter than the 8-character links used by CVS or Qualtrics initially.
By way of example, the link now appeared like: https://ql.tc/a1B2c3
I went back and checked, the original link still resolved to my survey, so now two shortened links pointed to the same URL. This started to get really interesting because on top of reducing the difficulty of walking the entire address space by 4,100 times, it also implied that the reduction might be doubled or tripled again if every text message gets a new six-character short code.
In fact, it appears like these short codes are very frequently generated, not only for surveys themselves, but other Qualtrics links. For example, links to "public results" dashboards also used the six-character address space as seen on this page accumulating links for COVID-19 resources for higher education libraries. One report has five separate short codes linking to it: aAaxhh, Q0TfA9, 7oXDoD, 0qevAA, and qR4a6x.
I should note that I never figured out, nor asked Qualtrics, what was generating these URLs. I generally assumed it was Twilio due to Qualtrics’ easy Twilio integration, but that wouldn’t make it clear which side of that integration actually generated the link.
Third Party Qualtrics Survey
Once I recognized Qualtrics from the contact tracing form, I began to see surveys from them all over. Of note, I also received a survey via text from a third party which behaved very similarly. While those surveys had a very low phishing appearance because they pointed directly to the third party’s well known website, they had a very similar structure of a one-character folder followed by a six-character alphanumeric code.
By way of example, the link appeared like: https://survey.ciofecaforensics.com/a/a1b2c3
I received three links to this form reminding me to fill it out, each one providing a different shortened URL with just 6-characters, all three of which resolved to the same survey. This validated the assumption that a new shortened URL was generated every time and shows that customers using Qualtrics’ product on their own domains likely have the same behavior. It also shows that an individual customer could dramatically expand its link address space and reduce the phishy-ness by using its normal domain.
Gallup Qualtrics Survey
While I was researching this issue, I received an email from Gallup polls, asking me to complete a survey. I imagine a text from them would have looked similar to the above links, but Gallup does not have my phone number. The email provided the full URL scheme as the text URLs redirected to.
For example, the URL appeared like: https://gallupinc.co1.qualtrics.com/jfe/form/SV_AAAAAAAAAAAAAAA?Q_DL=BBBBBBBBBBBBBBB_AAAAAAAAAAAAAAA_CGC_CCCCCCCCCCCCCCC&Q_CHL=email
URL Comparison
We have looked at links in six different forms, of which four were for Qualtrics. The lengths vary and the below chart highlights how big of a difference the varying lengths has on the total address space available. Why does the overall length matter? Because if a service had sensitive information protected only by its URL, the length of the shortest path to get to that page is all that protects it from my old friend Forza Bruta2.
Delivery Vector | Code Length | Alphabet3 | Possibilities |
---|---|---|---|
Qualtric’s email4 | 15 | a-zA-Z0-9 | 768,909,704,948,766,668,552,634,368 |
EN Express text | 16 | a-z0-9 | 7,958,661,109,946,400,884,391,936 |
CVS text | 8 | a-zA-Z0-9 | 218,340,105,584,896 |
Qualtric’s initial text | 8 | a-ZA-Z0-9 | 218,340,105,584,896 |
Qualtric’s reminder text | 6 | a-zA-Z0-9 | 56,800,235,584 |
Third Party text | 6 | a-zA-Z0-9 | 56,800,235,584 |
Interesting Data
While the link structures were interesting, the data behind the links was much more so.
Qualtrics Survey Overview
Qualtrics surveys run on a Javascript engine called the JavaScript Form Engine (JFE). This engine loaded its values in a line typically towards the end of the page that reads QSettings.setPT([bool], [large_hash]};
. Within the hash passed as the second argument to that function, the most interesting fields were “SM” (survey metadata), “ED” (embedded data), and “EDMETA” (embedded data metadata)5.
In order to play along at home, I put together this Ruby code snippet which pulls the “SM”, “ED”, and “EDMETA” values from any arbitrary Qualtrics survey. This uses a Quest Diagnostics survey as the example only because it was the first Google result for the domain:
require 'json'
require 'net/http'
# Helper function to make Markdown tables
def print_section(settings, tag)
return if !settings[tag]
settings[tag].sort.each do |item|
if item[1].is_a? Hash
item[1] = item[1]["value"]
end
puts "|#{tag}|#{item[0]}|#{item[1]}|"
end
end
# Set the target URL to fetch
uri = URI("https://feedback.questdiagnostics.com/jfe/form/SV_0Oi1BjI6TCEv2aq")
response = Net::HTTP.get_response(uri)
# Find the embedded QSettings JSON
# settings = response.body.match('QSettings.setPT\(true, (.*)\);')[1] # For older versions
settings = response.body.match('QSettings.setPT\(true, appData\);\s*}\s*}\)\(({.*})\)')[1]
parsed_settings = JSON.parse(settings)
# Print table header
puts "|Section|Variable Name|Value|"
puts "|-------|-------------|-----|"
# Print the Survey Metadata
print_section(parsed_settings, "SM")
# Print the Embedded Data
print_section(parsed_settings, "ED")
# Print the Embedded Data Metadata
print_section(parsed_settings, "EDMETA")
The output will look something like this, once rendered by markdown:
Section | Variable Name | Value |
---|---|---|
SM | BaseHostURL | https://feedback.questdiagnostics.com |
SM | BaseServiceURL | https://feedback.questdiagnostics.com |
SM | BrandDataCenterURL | https://iad1.qualtrics.com |
SM | BrandID | questdiagnostics |
SM | EDFromRequest | [] |
SM | FormSessionID | [REDACTED] |
SM | IP | [REDACTED] |
SM | IsPreview | false |
SM | JFEDataCenter | jfe1 |
SM | JFEVersionID | a023acfdc73515ae8de0cc04ef06970eb0cbb01d |
SM | LastUserAgent | Ruby |
SM | LinkType | anonymous |
SM | ProxyURL | https://feedback.questdiagnostics.com/jfe/form/SV_0Oi1BjI6TCEv2aq |
SM | QueryString | |
SM | StartDate | 2023-12-26 14:29:40 |
SM | StartDateRaw | 1703600980811 |
SM | SurveyID | SV_0Oi1BjI6TCEv2aq |
SM | SurveyVersionID | 9223370339281787751 |
SM | URL | https://feedback.questdiagnostics.com/jfe/form/SV_0Oi1BjI6TCEv2aq |
SM | UserAgent | Ruby |
SM | XSRFToken | [REDACTED] |
SM | dataCenterPath | jfe1 |
ED | Q_CHL | anonymous |
ED | Q_Language | EN |
ED | Q_LastModified | 1701189881 |
ED | Q_URL | https://feedback.questdiagnostics.com/jfe/form/SV_0Oi1BjI6TCEv2aq |
ED | SID | SV_0Oi1BjI6TCEv2aq |
ED | SurveyID | SV_0Oi1BjI6TCEv2aq |
ED | UserAgent | Ruby |
This example is an “anonymous” survey, so the results aren’t interesting. The surveys I ran into from the links mentioned in the first section proved otherwise.
Caveat: It is important to note at this juncture that Qualtrics is clear in its documentation that "Embedded data may be visible to individual survey respondents and should not contain sensitive data that a respondent is not intended to view." A failure to read the fine manual on the part of a Qualtrics customer is not Qualtrics' fault. The following sections detail places Qualtrics customers failed to do just that.
Contact Tracing
Upon loading the contact tracing page, I was confronted with the same request as CVS’s website: to confirm my date of birth. I opted to peruse the page’s source before entering anything since I had never used Qualtrics before. I was shocked to see my date of birth in the QSettings hash! In fact, I was met with eight pieces of my personally identifiable information (full name, date of birth, age, address[street, city, state, and zip], and phone number) and one piece of my medical information (date of my positive test). Contacts of those who tested positive were also included. Had I responded via email, there also was a field for my email address.
For example, in my survey’s “EDMETA” section, I saw this (plus a lot more that has been snipped for brevity):
Section | Variable Name | Value |
---|---|---|
SM | EndDate | 2022-10-14 01:22:51 |
SM | EndDateRaw | 1665710571649 |
SM | StartDate | 2022-10-13 22:06:25 |
SM | StartDateRaw | 1665698785546 |
EDMETA | Account_Id | [REDACTED] |
EDMETA | Address_City__c | [REDACTED] |
EDMETA | Address_State__c | [REDACTED] |
EDMETA | Address_Street__c | [REDACTED] |
EDMETA | Address_Zip_Code__c | [REDACTED] |
EDMETA | Best_Phone_for_Web_Survey__c | [REDACTED] |
EDMETA | County__c | [REDACTED] |
EDMETA | First_Exposure_Date__c | [REDACTED] |
EDMETA | First_Specimen_Collection_Date__c | [REDACTED] |
EDMETA | Full_Name_Middle_Initial__c | [REDACTED] |
EDMETA | Last_Exposure_Date__c | [REDACTED] |
EDMETA | PersonBirthdate | [REDACTED] |
EDMETA | PersonEmail | [REDACTED] |
EDMETA | SF_Age__pc | [REDACTED] |
Anyone with the URL (or any of the shortened URLs that point to it) could bypass the form’s authentication by reading the “PersonBirthdate” field. A malicious actor wouldn’t even need to do that, since all of the personal and medical information is present from the start. This is why reducing the total address space from ~218 trillion possibilities down to ~57 billion shortened URLs is so concerning, the PII of everyone in my state who received this survey is protected not behind a birthday confirmation as most health information is, but simply by knowledge of the URL.
To put a fine point on it, anyone who browsed to any of these surveys was provided all of the PII and medical data for the survey participant in the page's source, before authentication.
What stood in the way of a malicious person harvesting all of the surveys in bulk is that each survey had an expiration listed in the “Survey Metadata” section. For example, I had about a day and a half to complete the survey before it would expire and trying to visit an expired survey link yielded a page that reads “Your survey session has expired and you cannot continue taking the survey” without any user data being present. If there was a way to bypass the expiration the information leak would get even more interesting (more on that later).
Gallup Qualtrics Survey
Despite a decent privacy policy, I was fairly shocked at the embedded data in Gallup’s survey6:
Section | Variable Name | Value |
---|---|---|
EDMETA | DEMO_AGE | [REDACTED] |
EDMETA | DEMO_BUSINESS | [REDACTED] |
EDMETA | DEMO_CHILDREN | [REDACTED] |
EDMETA | DEMO_DIVISION | [REDACTED] |
EDMETA | DEMO_DOB | [REDACTED] |
EDMETA | DEMO_EDUCATION_2017 | [REDACTED] |
EDMETA | DEMO_ETHNICITY | [REDACTED] |
EDMETA | DEMO_GENDER | [REDACTED] |
EDMETA | DEMO_INCOME_2017 | [REDACTED] |
EDMETA | DEMO_LGBT | [REDACTED] |
EDMETA | DEMO_MILITARY | [REDACTED] |
EDMETA | DEMO_RACE_2015_NEW | [REDACTED] |
EDMETA | DEMO_RACE_AMERICAN_INDIAN_NEW | [REDACTED] |
EDMETA | DEMO_RACE_ASIAN_NEW | [REDACTED] |
EDMETA | DEMO_RACE_BLACK_NEW | [REDACTED] |
EDMETA | DEMO_RACE_NATIVE_HAWAIIAN_NEW | [REDACTED] |
EDMETA | DEMO_RACE_WHITE_NEW | [REDACTED] |
EDMETA | DEMO_REGION | [REDACTED] |
EDMETA | FULL_NAME | [REDACTED] |
EDMETA | HOME_PHONE | [REDACTED] |
EDMETA | INCENTIVE_AMOUNT | 1 |
EDMETA | INCENTIVE_TIME | POSTPAID |
EDMETA | INCENTIVE_TYPE | RYBBON |
EDMETA | INCENTIVE_YN | Y |
EDMETA | ZIP | [REDACTED] |
With a valid URL to a Gallup poll, you knew someone’s name, age, phone number, gender, race, ethnicity, and rough income level. Some aspects appeared to contradict the privacy policy, for example Gallup said it does not disclose someone’s military or veteran status for business purposes, yet that was clearly seen in DEMO_MILITARY
. Also, interestingly, you would know how Gallup planned to incentivize their poll in the INCENTIVE_*
fields, hopefully that value isn’t trusted input from the user (more on that later).
Third Party Survey
Thankfully, the third party survey did not put any sensitive information in their form, it only identified my phone number without tying it to me.
Data Comparison
While each survey form had different data in it, two of the three Qualtrics surveys I received had personally identifiable information included before authentication. Clearly Qualtrics customers were not consistently heeding the warning that ED information would be available to anyone with the URL.
Trusting Data
Trusted Survey Metadata
Throughout this research, I was puzzled by the design decision to push all of this interesting data to the client filling out the survey. While I don’t know all of the use cases, I would have expected that the combination of Panel Member ID, Survey ID, and Distribution ID would be enough to join the embedded data on the backend. Even more puzzling, it appeared that JFE sent back the “SM”, “ED”, and “EDMETA” fields with each response, which unnecessarily increased Qualtric’s network traffic. Unnecessarily unless… they were reading the input.
I didn’t think the metadata for a survey, having been sent to the untrusted responder, would be trusted, but I wanted to make sure. As an experiment, when I responded to the Gallup poll seen above, I used Burp Suite to intercept one of the responses and changed an EDMETA field. The subsequent responses I received from the Qualtrics server for that survey had that field set to the value I provided.
Setting Variables via the URL
In addition to intercepting the JSON sent back and forth, the URL can also be used to set variables in the objects. You can find examples of people taking advantage of the ability to set variables in GET requests if you poke around the Internet. For example, some enterprising New York University students were sick of filling out their daily COVID-19 screener and automated the submission of the survey. While there isn’t a great way to completely prevent that, it highlights the value in using some of Qualtrics’ more advanced features, such as using authenticators to make sure the right person is responding to your survey and not a cron job.
Trusted URLs
Given how much personal information was available pre-authentication on these surveys, the information is really only protected by the URL itself. For the longer URLs, we saw that most of the entropy in the URL is the Panel Member ID, since the Survey ID and Distribution ID can be known by other recipients. For the shortened URLs, the address space is small enough that it is extremely plausible that one could walk the entire space and build up a mapping of Distribution IDs that belong to Survey IDs and Panel Member IDs that belong to Survey IDs.
The final feature protecting the information then is the fact that many surveys expire within just a few days. Unfortunately, a bug existed to bypass the survey expiration by using an arbitrary current Distribution ID for a Survey ID to pull a previously expired Panel Member ID’s information. It appeared7 that there was a bug in how Qualtrics was checking for an expired survey. Rather than check if the specific recipient had been contacted too long ago, it checked if the distribution was still valid. Unfortunately, it did not appear to check if the recipient was part of that distribution.
In other words, because a survey can have multiple Distribution IDs, any currently valid Distribution ID would give access to a survey for any user who had received the survey, even if the original Distribution ID the recipient was contacted through was invalid.
A friend of mine had acquired COVID a few months earlier and never completed his state contact tracing survey. While the link was solidly expired, I asked if he would forward me his text so that I could see it, explaining that I may see his personal information, and he agreed. Below is how the URLs compared, we both had the same survey received via text message, but different distributions and panel member IDs.
Field | My URL | His URL |
---|---|---|
Survey ID | AAAAAAAAAAAAAAA | AAAAAAAAAAAAAAA |
Distribution ID | BBBBBBBBBBBBBBB | EEEEEEEEEEEEEEE |
Panel Member ID | CCCCCCCCCCCCCCC | FFFFFFFFFFFFFFF |
Channel Categorization | smsinvite | smsinvite |
I found that if I used his Panel Member ID in place of mine, and left the rest of my URL the same it assumed I was him! I was able to read back to him his date of birth, the date he tested positive for COVID, and the phone number he had used to register for the test, much to his astonishment.
What is the Problem?
At this point we’ve identified a few issues with Qualtrics surveys that don’t seem too bad on their own. Is there a way to put them together to form a bigger problem?
- SMS respondents can receive at least one, likely multiple six-character shortened URLs pointing to their survey
- That six-character shortened URL can lead to the full URL which gives the distribution ID, panel member ID, and survey
- That URL, if not expired, contained an information disclosure vulnerability yielding data the survey designer may not realize is public
- That URL, if expired, was vulnerable to an access control bypass by using a current distribution ID for the same survey to do the same
It looks like, even without attacking the 15-character panel member ID, an attacker could launch a reasonable attack on any text-based respondents by walking the shortened URL space. This wouldn’t be possible using any of the other shortened URL schemes given above, but an address space of less than 52 billion is not nearly enough. At the time this research was done, it was plausible to make the 52 billion requests required to walk the space in a reasonable amout of time and with a hobbyist’s budget8, but it is important to note that walking the entire address space is not the only way to identify valid shortened URLs.
For example, Qualtrics uses Twilio to send its SMS messages9. Twilio keeps the messages it sends on your behalf until you request them to be deleted10. This means a hypothetical breach in Twilio could be used to look at the text messages sent on behalf of Qualtrics. In addition, shortened URLs can be found in caches, such as virus scanning tools and domain reputation sites, many of which keep record of where the 301 redirect goes. These were likely uploaded by people who were not thinking about the implications of the world getting their panel member ID and survey.
Fixes
Very quickly after reporting these issues:
- My state amended its survey form to not include PII.
- Qualtrics fixed the bug allowing a current distribution ID to provide access to data from an expired survey.
- Gallup removed the PII from its surveys and now requires the respondent to fill it in.
Conclusion
After pouring through its documentation, interacting with its Security and Privacy teams, and digging into this incident, I became a fan of Qualtrics. They were genuinely pleasant to deal with, responded quickly, and most of what I needed to know about the service was present in their public documentation. It is always easy to blame the service provider, but everything I read in Qualtrics’ documentation made it clear that the PII listed above would be available to anyone with the URL.
The fault lay with the specific customers creating these surveys who either did not read the documents or did not understand the implications. Yet it was clear from the Third Party example given above that some customers got everything absolutely right and used the platform very well, keeping their data secure and their customers phish-proof.
So please, if you're signing up for a new service, read the fine manual!
Disclosure Timeline
- October 14, 2022: Alerted Qualtrics Privacy and Security teams to the issue.
- October 14, 2022: First attempt to contact state Department of Health Privacy Office.
- October 18, 2022: Alerted state Department of Health Privacy Officer to the issue.
- November 2, 2022: State Department of Health Privacy Officer noted that they had met with Qualtrics Privacy and Security teams and that Qualtrics had quickly remediated the issue and performed an investigation, determining there was no unauthorized access to personal information.
- December 12, 2024: I provided a draft of this article to the Qualtrics Privacy and Security teams, seeking any comments they might have.
- March 3, 2025: Qualtrics Security Team politely indicated they had no concerns with this article as written and thanked me for giving them the opportunity to review.
Footnotes
-
Cover photo by @Goumbik on Pexels. ↩
-
“Brute force”. ↩
-
This appears to be the value based on my observations, it could be wrong. ↩
-
This number assumes prior knowledge of a survey form and distribution ID for reasons that are explained later in the post. ↩
-
As of January 2023, I am no longer seeing EDMETA sections in any Qualtricks surveys I receive. It seems Qualtrics decided to remove this opportunity for missteps from its clients. ↩
-
Gallup polls no longer contain this information and ask you to enter it where required. This issue was never reported directly to Gallup because of the timing of changes on Qualtrics’ service. The first survey I received after Qualtrics fixed the EDMETA section and enforced survey timeouts no longer included the demographic information. ↩
-
This is based on my own guess based on how the site responded to my checking a trial URL generated from another consenting party’s recipient ID. This could be wrong, I did not attempt to reverse engineer the site or brute force further proof. ↩
-
No, I did not walk the entire space, but I did do some proof-of-concept testing that validated the rate that was needed was possible while being careful not to impact any service. Note that “reasonable” and “trivial” are not the same thing and this ended up being a fun engineering problem in and of itself. ↩
-
According to Qualtric’s SMS Distributions help page. ↩
-
According to Twilio’s Twilio SMS message and traffic storage help page. ↩