Wednesday, September 07, 2016

How to set up Facebook Login Deauthorize Callback with ColdFusion

Today, I continued my fun development on CrossTrackr with the Facebook Graph API as I had a few things to fix or update (to say the least). While doing this, I noticed that there was a callback for when a user deauthorized your app. Which currently on CrossTrackr, if a user did this and then tried to post, it would catch it and then just reset the user's settings. Although that worked, I wanted a better solution and this offered it by simply allowing me to complete the process on my end as soon as they executed the deauthorization.

In the most simple explanation, facebook simply sends a form post with a signed_request field value. You need to take this value and decode it properly so you can view the user_id, find in your system and then do what is necessary (depending on your implementation).

I could not find specific info on what was being returned on the Facebook developers portal (maybe because I did not look hard enough before googling) but lucky for us, there are many people out there that share their knowledge when they themselves figure it out, which is all I am doing here myself. The code that I have below is basically a port of a few PHP snippets and some other smart developers that were able to create an equivalent to PHP's hash_hmac.

I hope this helps you out if trying to do this on ColdFusion.

I'd like to thank the contributors of the following posts.

Facebook Deauthorize Function and Usage Example

Monday, September 05, 2016

Emoji support with ColdFusion and mySQL

So for a while, I have been trying to get Emoji support on CrossTrackr and no matter what I did I would still get an error until I finally threw my hands in the air and gave up. So what I ended up doing is using some code from this post on Drupal's blog, https://www.drupal.org/node/2043439, which allowed me to clean up the string before submitting to the database. When I found this post I was extremely happy but when I tried to execute the regex examples using reReplace() I would get the following ColdFusion error:

Malformed regular expression "/[\x{1F600}-\x{1F64F}]/".

This led to more frustration and then moving to my next solution which was to make a call to a PHP page using CFHTTP.

An example of how I did that can be seen in the following 2 gists.

ColdFusion Function making http call to local PHP File The local PHP File

Today I decided to attack this issue again as I got tired of getting errors, especially when I introduced new fields which I would forget to sanitize and users would try to use an emoticon 😫 . I found this great post (How to support full Unicode in MySQL databases) from Mathias Bynens @mathias which got me the answer I was looking for. See, I had already understood that I needed to set my fields to utf8mb4, but even though I did I would get the error, reason I went with just cleaning the string. In this post there is a section on modifying connection, client, and server character sets which was the piece I was missing. I just needed to set a couple of settings on mySQL server cnf file in order for data from ColdFusion to be able to be saved. Which are as follows:

The settings that actually did the trick where character-set-server which sets the default character set to use, character-set-client-handshake which ignores character set information sent from client and uses the server character set instead and collation-server which sets the default collation. The settings under the [mysql] and [client] parts did not really affect it working but I left them in regardless. I was previously using utf8 as the default and since utf8mb4 is fully backwards compatible with utf8, there was no data loss when I updated the columns. He does go into modifying the database, table and columns but when I tested, all I did was work with the columns that I needed to support and modifying the database or table itself was not necessary, thus not creating any issues with my index keys as he explains. An example of how I update the character set of a specific column is as follows:

ALTER TABLE `table_name` CHANGE `column_name` `column_name` TEXT CHARACTER SET utf8mb4;

Again, in his example he does a little more and sets the collation to utf8mb4_unicode_ci but after testing, the default collation for utf8mb4 also worked. Once I added the settings to mySQL and restarted and removed my cleanEmoji() wrappers in my ORM files, my saves no longer threw an error. One thing I did have to remove is surrounding my output with encodeForHTML() as that would replace the emojis with question marks.

Now in doing this today and finally getting it to work I did figure out something else, and that is that the call to PHP is not really necessary. We can use those regex patterns using Java's internal replaceAll() string function. So now I can wrap saves to fields where I do not support emoji's without incurring an http call from the server to itself and PHP handling the work for me. Below is the updated cleanEmoji(), which I now call cleanEmojiWithColdFusion().

I hope this helps you as it helped me get Emoji's (High Ascii Values) working on my App. I will try to see what is required if working with MS SQL and either update this post or create a new one.

Tuesday, May 24, 2016

ColdFusion 10+, IIS 7+, Custom Errors and a little thing called TrySkipIisCustomErrors

Today as I was debugging some issues that FuseGuard allowed me to see, it appeared that on my IIS Server my custom error page was being rendered after the IIS error page.

At first I was confused as I know I can control my 404 as I had set it properly in my Web.Config file as such:
<httpErrors existingResponse="Auto">
 <remove statusCode="404" subStatusCode="-1" />
 <error statusCode="404" path="/?action=main.404" responseMode="ExecuteURL" />
</httpErrors>
With the existingResponse attribute set to "Auto", it leaves the response untouched only if the SetStatus flag is set. Which I thought that meant as long as I set it in ColdFusion it would skip trying to show the IIS error page. Now, not to confuse further, the settings above worked for my 404s because I was removing how the server handled it and applying my own ExecuteURL setting. The issue was when i was trying to do a custom 503 (as FuseGuard shows when a request is blocked).

Now there is a value of PassThrough that can be set for existingResponse and it would work but the problem here is that if you have lets say a RewriteRule that blocks a request and sets it as a 503 nothing displays. So this was not going to work for me in that scenario.

More on IIS Custom Errors

Here is where TrySkipIisCustomErrors comes into play. Basically for existingResponse="Auto" to work properly we must be able to set Response. TrySkipIisCustomErrors to true but there is no way to do this in ColdFusion, trust me I tried hacking at it using getPageContext(). So then I started to google an alas there is a fix now for some of us.

While the solution can be found in either of the 2 following posts, you still have to search within the content to find it so I thought I would just show you and hopefully make future google searches a little easier.

http://blogs.coldfusion.com/post.cfm/onmissingtemplate
https://bugbase.adobe.com/index.cfm?event=bug&id=3982328

As of ColdFusion 10 Updater 18 and ColdFusion 11 Updater 7 there is a new setting that you can find in your isapi_redirect.properties file for your connector that is called iis_skip_custom_errors_enable which defaults to false. Go into that file or files (if more than one connector) and set it to true. Restart your IIS site (ColdFusion does not have to be restarted) and like magic it all works now.



To get a visual of what I am talking about below is a before and after of what my 503 page was coming up like.

BEFORE


AFTER


And since the setting is set to Auto, if nothing is set by ColdFusion, like one of my RewriteRules which blocks access to a certain directory, then the default IIS page is displayed as such.

Wednesday, May 11, 2016

ColdFusion 11 Update 8 is out now!

A new update is available for ColdFusion 11 which includes the following changes:

  • Tomcat upgrade to 7.0.68
  • Addresses a vulnerability mentioned in the security bulletin APSB 16-16.
  • Several important bug fixes for security, language, AJAX, and other features.

For me specifically, this fixes the CachedWithin bug with QueryExecute() where it ignored it.

All the bugs fixed can be found here.

ColdFusion 11 Update 8

Monday, May 09, 2016

ColdFusion IIS 10 HTTP/2 - Safari Bug

For a while I have been dealing with a bug that I had no idea how to even explain to the ColdFusion team and after telling them several times about it, nothing was ever resolved. Today though, I believe there is enough to show how and why this is occurring and only with Safari.

On Windows 10 running IIS 10, the HTTP/2 protocol is enabled by default and all you need to do to take advantage of it is have your site served over HTTPS. Believe it or not it is actually that simple.

The Bug
So when I would browse my site on any browser I would see that the connection was downgraded to http/1.1 which is absolutely ok and the site would still render, but when I would try it on Safari it would just go into an endless loop causing a lot of connections opening up on the server. I have to give it to Fusion-Reactor here because it was what allowed me to easily see this in action the first time.

Why it was a problem for me
Now any other day, because this is my dev box it would not matter but on this particular dev box, I needed to test a Cordova App I built that is pointing to a Webserver and although it worked on production when I pointed it to my dev box it would just never render. So I then tried to open in Safari on my desktop (because we know it is iOS Safari on the phone) to see what was going on and I would just get a white page, the spinning wheel and a lot of connections on ColdFusion.

I decided to finally open up my console (not web) and I started seeing the following:

Safari[2061]: tcp_connection_destination_handle_tls_close_notify 60 closing socket due to TLS CLOSE_NOTIFY alert
tcp_connection_tls_session_error_callback_imp 60


Those errors would just continue as long as I left Safari trying to connect. Once I stopped Safari, the messages would stop and Fusion-Reactor graphs would go back to normal. You can see all of this in the following video.


The temporary solution
So until either the Safari team or the ColdFusion team fixes this, the only solution is to disable HTTP/2 on Windows 10 which is easy by doing the following:

  1. Open the registry editor (regedit)
  2. Browse to Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\HTTP\Parameters
  3. Enter 2 new DWORD Values EnableHttp2Cleartext and EnableHttp2Tls
  4. Set their values to 0
  5. Reboot


Now when you browse any HTTPS site running on IIS 10 it is server as HTTP/1.1, not causing the connection downgrade and therefore working properly in Safari.

Tuesday, January 12, 2016

ColdFusion WebSocket Proxy and IIS 8+ - 500 Error

Today I ran into an issue in my development environment that was one of those "Duh" moments. If you are using the WebSocket Proxy with IIS we already know the following is required.
  1. IIS 8+ with WebSockets Installed
    • Windows 8+ : Can be found in Control Panel > Programs and Features > Turn Windows Features on or Off > Internet Information Services > World Wide Web Services > Application Development Features > WebSocket Protocol (check it)
    • Windows Server 2012+ : Same as above but the steps are a few more screens. You may also start from the Server Manager (Top Right: Manage > Add Roles and Features)
  2. Run wsconfigproxy.exe (as administrator) which can be found in {{ColdFusionInstallDir}}/cfusion/bin/wsconfigproxy.exe
  3. Set "Use Proxy" in ColdFusion Administrator (restart may be required if not already set)
At this point everything should work without a problem and most of the times it does. I have ran into permission issues, especially when you go thru the lock down guide and you did not set the required permissions on the config/wsproxy directory. If all the above is correct and you still have an issue, like I did today, check one last thing.

Last time I configured the app pool on this app I was testing I had set the .NET CLR Version to "No Managed Code" and when the cfws directory was created it used the parent App Pool. The fix is simple, set the .NET CLR version back to a valid version or create another App Pool with a CLR assigned and bind it to the cfws folder since it is created as a virtual application. Below are some images that show the error I was receiving (after I allowed errors to show on localhost) and how to assign the fix. An easy way to test that they can be connected to is by browsing to the /cfws/ path of your domain. In an http call you should receive a good 200 response.

UPDATE
Do not use a different app pool, just ran into an issue that when I sent a call to WsPublish on the server side it messed with my Session scope. The only fix is to make sure they both use the same App Pool and that it is set to use a .NET CLR. (duh moment #2 of the day)

Bad Request

Causes Error Works Again


Good Request