It was going to happen at some point; a CRM hotfix rollup that broke existing supported customisation code. Update Rollup 7 adds some security changes that apply to the Attachment/download.aspx page. As a result the example code documented here in the SDK no longer works.

If you try the code, the user gets the error message "Access Denied, Invalid Operation". If you enable tracing, you see a message like the following:
"Message: INVALID_WRPC_TOKEN: Validate WRPC Token: WRPCTokenState=Invalid, TOKEN_EXPIRY=4320, IGNORE_TOKEN=False, TOKEN_KEY=b1Nd0byfEd6+gwAZuez7cauYiRnfHuMLAquFY1Ks22dHgxZiW5IrxSobkv9aVfbC, ErrorCode: -2140991221"

The fundamental problem is that CRM now expects additional parameters on the query string that contain a Token, and there is no way for us to generate that token. There's a significant question about why this change was made, but I'll leave that for another time.

In the meantime, there is a workaround, providing you have access to the registry. It is possible to disable the token checks via a registry change. To do this, create a DWORD registry key named IgnoreTokenCheck under HKLM\SOFTWARE\Microsoft\MSCRM" and set the value to 1, then recycle the CrmAppPool application pool for the change to take effect. I've not checked the behaviour in detail, but I expect this registry change will disable the token check for all CRM operations, and not just the attachment download. If I find more I'll post it here.

There's an argument as to whether this opens a security hole, as tokens are designed to stop one-click attacks, so you need to consider the implications. My personal view is that, although I normally err on the paranoid side when discussing application security, I think the risks of disabling token checking are minimal.

ps. If you're hoping that this post will also give a list of other useful but undocumented registry settings for CRM, then you're as out of luck as I am. I was made aware that there might be a registry fix by another MVP (thanks Matt Parks), but had to disassemble the CRM code to find out what it was.