5

I'm having trouble understanding the upcoming change to how Marketing Cloud will interpret subject lines containing inline AMPScript or personalization strings. As from Feb 21, 2023, Marketing Cloud will stop processing nested AMPscript in email subject lines.

The example they provide in this knowledge article states:

subject:  %%=V(@subject)=%%

HTML body:

%%[
    SET @dealType = Lookup("Deals", "DealType", "DealCode", DealCode)
    SET @subject = "Check out the latest deals on %%=V(@dealType)=%%!"
]%%

...will resolve as:

Check out the latest deals on %%=V(@dealType)=%%!

However, the documentation goes then explains if you're using personalization strings as subject lines, for example %%Subject%%, will also "result in nested personalization within the subject line" (i.e. it will break), but the workaround is to wrap the attribute with a TreatAsContent function, for example:

%%=TreatAsContent(Subject)=%%

Now that you're up to speed with this imminent change, I'm trying to understand whether the following pattern will be affected by this update. I'm using the following subject line:

%%=TreatAsContent(@subject)=%%

And I have some AMPscript code in my email body looks something like this:

%%[ 
   var @subject
   set @subject = Lookup('SubjectLines', 'Subject', 'Email', emailName_) 
]%%

And the Subject field in the DE might contain the value:

Thanks for supporting %%ChildFirstName%%

My question is, how will my subject line be interpreted with this change? The docs explain that email subject lines are currently processed twice to parse nested variables/AMPscript. I get that. But is my subject line considered as a double pass? I think it might be. And if this subject line will be interpreted as:

Thanks for supporting %%ChildFirstName%%

...then what is the best workaround for subject lines that are stored in a DE field which contain inline AMPscript or personalization strings?

I'm guessing that the following workaround might do the trick, but in absence of more elaborate documentation, this is really just an assumption:

subject: %%=v(@subject)=%%

HTML body: 

%%[ 
   var @subjectStr, @subject
   set @subjectStr = Lookup('SubjectLines', 'Subject', 'Email', emailName_)
   set @subject = TreatAsContent(@subjectStr)
]%%

1 Answer 1

4

I took a very deep dive into this for a few clients and most of what you said is correct. First I am going to dive into the use-case example you shared:

Now that you're up to speed with this imminent change, I'm trying to understand whether the following pattern will be affected by this update. I'm using the following subject line:

%%=TreatAsContent(@subject)=%%

And I have some AMPscript code in my email body looks something like this:

%%[ 
  var @subject
 set @subject = Lookup('SubjectLines', 'Subject', 'Email', emailName_) 
]%%

And the Subject field in the DE might contain the value:

Thanks for supporting %%ChildFirstName%%

My question is, how will my subject line be interpreted with this change?

So for this I am going to break it down into phases.

  1. First phase of your subjectline is when it is sitting in the data extension. In this phase, it is a string that is literally output as Thanks for supporting %%ChildFirstName%%

  2. Second phase In this phase, the value is pulled from the data extension and pushed to an AMPscript variable. The value here is still stored as a string and literally output as Thanks for supporting %%ChildFirstName%%.

  3. Third phase This is where things are changing.

  • Previously (prior to the new change taking effect) if you used %%=v()=%% to output the variable set in the Second phase, it would actually treat the personalization strings and ampscript functions inside that string as code and not strings - rendering your subject to Thanks for supporting Eliot despite it being a string value in the variable.

  • Now (after the change takes effect) utilizing %%=v()=%% will remove this extra processing phase and will instead just output the string stored in the variable (Thanks for supporting %%ChildFirstName%%). You would have to utilize the TreatAsContent() function to force another pass on this string to have it recognize the AMPscript and Personalization strings inside of it. Which is why utilizing %%=TreatAsContent(@subject)=%% as your subjectline output solves any issues caused by this change (mimics the existing functionality done with %%=v()=%% prior to change).

And to answer the second part:

Subj: %%=TreatAsContent(@subject)=%%

AMPscript: set @subject = Lookup(...)

------------------------------------------

Subj: %%=v(@subject)=%%

AMPscript: set @lu = Lookup(...)
           set @subject = TreatAsContent(@lu)

Both of these will work exactly the same and solve the issue.

Now, that being said. Utilizing %%=TreatAsContent()=%% in this way is a quick and easy fix to this - but it also completely negates the whole reason for them to implement this change. The idea is to help reduce risks and security holes by removing 'expected processing' areas and reduce chance of malicious injection.

Long story short, TreatAsContent is a quick fix, but not one I would recommend long term. Long term, I would instead look at building and processing your Subjectline prior to the output in the subjectline.

This unfortunately means that best practice would be not to utilize personalization strings and ampscript variable calls inside of a single DE string. There are ways to work around this, for instance you can utilize replaces or multiple columns/fields, etc. to build it out instead.

BUT if, in all honesty, its just not feasible or valuable to do that, the TreatAsContent option is viable, especially as at that point the assumption of 'expected processing' will no longer be guaranteed, so it should be even further lower risk.

2
  • 1
    Thanks for the elaborate answer! In short, you are confirming that I don't actually need to do anything. And I'm with you regarding the TreatAsContent workaround which could open a backdoor to a malicious attack (where an attacker completes a landing page form and adds an AMPscript code block in a form field, which is then stored in a DE and used in an email) — kind of like SQL injection, but using AMPscript. I've tried elaborate workarounds like using RegExMatch to find %% delimiters and substitute them, but this will always require TreatAsContent Jun 29 at 22:45
  • 1
    I'll give others an opportunity to propose a solution before accepting this answer. Jun 29 at 22:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.