Automatically Evaluating Compressibility

Fiddler’s Transformer tab has long been a simple way to examine the use of HTTP compression of web assets, especially as new compression engines (like Zopfli) and compression formats (like Brotli) arose. However, the one-Session-at-a-time design of the Transformer tab means it is cumbersome to use to evaluate the compressibility of an entire page or series of pages.

Introducing Compressibility

Compressibility is a new Fiddler 4 add-on1 which allows you to easily find opportunities for compression savings across your entire site. Each resource dropped on the compressibility tab is recompressed using several compression algorithms and formats, and the resulting file sizes are recorded:

Compressibility tab

You can select multiple resources to see the aggregate savings:

Total savings text

WebP savings are only computed for PNG and JPEG images; Zopfli savings for PNG files are computed by using the PNGDistill tool rather than just using Zopfli directly. Zopfli is usable by all browsers (as it is only a high-efficiency encoder for Deflate) while WebP is supported only by Chrome and Opera. Brotli is available in Chrome and Firefox, but limited to use from HTTPS origins.

Download the Addon…

To show the Compressibility tab, simply install the add-on, restart Fiddler, and choose Compressibility from the View > Tabs menu2.

View > Tabs > Compressibility menu screenshot

The extension also adds ToWebP Lossless and ToWebP Lossy commands to the ImageView Inspector’s context menu:

ImagesMenuExt

I hope you find this new addon useful; please send me your feedback so I can enhance it in future updates!

-Eric

1 Note: Compressibility requires Fiddler 4, because there’s really no good reason to use Fiddler 2 any longer, and Fiddler 4 resolves a number of problems and offers extension developers the ability to utilize newer framework classes.

2 If you love Compressibility so much that you want it to be shown in the list of tabs by default, type prefs set extensions.Compressibility.AlwaysOn true in Fiddler’s QuickExec box and hit enter.

Putting Users First

When I worked on Internet Explorer, the team was proud of the fact that we could claim to be more aligned with our users’ goals than either of our major competitors (both of whom were funded almost entirely by advertising). IE, the story went, was paid for by users who purchased Windows, and thus our true customers were our users, not advertisers.

Over eight years on the team, there were very few instances where a decision was made that seemed to violate that “Users first, always” mantra (“Suggested Sites” being one noteworthy exception).

I was most proud of the work done around the IE Search Provider APIs, which made it easy for IE users to use the search engine of their choice, even though we knew that users’ choice would often not be Microsoft’s offering.

Add Search Provider (showing make default)

Last year, I was disappointed to see that Microsoft started removal of the Search Provider APIs, first deprecating them into legacy document modes, and next omitting them from the new Microsoft Edge browser. The result was that users had to follow a convoluted set of steps to add search providers for DuckDuckGo, Google, Wikipedia, etc. As a developer who loved using custom search providers for topic-specific searches on MSDN, StackOverflow, Amazon, and the like, I was really disappointed to see this change. I was only heartened to see this user-hostile change hadn’t been backported to earlier versions of Internet Explorer.

I recently upgraded Windows 10 to build 11082. Upon opening Internet Explorer 11, the following modal dialog box appeared:

srsly

I like to think that this dialog would never have shipped in the years I worked on IE. First, and most glaringly, the default option is to hijack the user’s search provider and homepage to Microsoft-owned properties. Next, the dialog box tries to justify this hijacking by implying that IE didn’t previously protect these settings (false) and that “websites” could “silently change” these settings (false). Clicking “Click here to learn more” takes the user to a page (delivered insecurely) which vaguely hand-waves about the threat of local malware, and says nothing about misbehaving websites.

So, if Microsoft is now “protecting” the settings they’ve just changed, how are they doing it?

Let’s have a look at the new version of that Add Search Provider dialog box we saw earlier. See what’s missing?

Add Search Provider (missing "make default")

That’s right—the choice to change your default search engine has been removed. (The option is now buried in a subtab of a subdialog of the Internet Options dialog.)

Ick.

 

-Eric Lawrence

SHA-1 Certificates Blocked By Authenticode

Twitter started to light up a bit tonight with folks who are having problems with signatures; both third-party ISVs:

Twitter post about bad signature

Signature is invalid or corrupt
The signature is corrupt or invalid.

… and even Microsoft’s own SysInternals utilities show1 an error:

Twitter complaint about bad signature

Signature is invalid or corrupt

Developers are surprised to see their workflow suddenly broken and wonder why.

The problem is outlined here – the tl;dr is that you must use a SHA256-signed certificate when codesigning any file after January 1st, 2016. If you failed to timestamp your file when you signed it, the date of signature cannot be determined and today’s date is used.

Confusingly, if you examine the File Properties in Windows Explorer, it will say that the signature is OK:

Explorer UI shows OK
This digital signature is OK. But not really.

To see the problem, you must dig into the certificate details:

SHA1 certificates
SHA1-signed Certificates

To fix this problem, you must

  1. Replace your code-signing certificate with a SHA256-signed certificate. Your CA should be willing to do this for free; if they aren’t, a little public shaming on Twitter will probably change their mind. Note: The entire certificate chain (except the root) must be SHA256, not just your certificate.
  2. Re-sign your files with the new certificate
  3. Accept that Windows XP SP2 and earlier don’t understand SHA256 certificates and will treat the file as unsigned. This is fine; XP SP3 resolved that limitation and users on XP have much worse problems to worry about anyway.

After you upgrade to the proper certificate, you should look into dual-signing your binaries so that the Authenticode signature itself contains both SHA1 and SHA256 signatures; this isn’t strictly required yet, but may be in the future. You should also follow other best-practices, including time-stamping and using a hardware token.

Stay secure out there!

-Eric Lawrence
1 At first, when I tried this using the SysInternals site, I didn’t see any complaints about the signature. That’s because the http://www.sysinternals.com site sends its binaries inside a .ZIP file. I’m using 7-Zip, which has a significant security bug– it fails to propagate the Mark-of-the-Web from a .ZIP to the files extracted from a ZIP file; as a consequence, Windows and SmartScreen won’t recognize that the files are from the Internet. If you’re not using Explorer’s built-in ZIP engine (which propagates MOTW properly) you can download executables directly from live.sysinternals.com to see the SHA1 problem.

Authenticode in 2016

Last month, I noticed that my eToken USB code-signing key only supports SHA1 and not SHA256. I began hunting for a replacement that can sign using the stronger hash. Fortunately, I didn’t have to look far—the Yubico YubiKey 4 is $40 and supports SHA256, RSA 4096, and ECC p384. Beyond supporting stronger algorithms, it seems to integrate better with Windows – I don’t need to install third-party software to use it after loading my certificate with the YubiKey PIV Manager.

To take advantage of SHA256, I needed to update my scripts to use signtool.exe instead of the older signcode.exe, which only supports SHA1.

My script is simply:

signtool sign /d "Brotli [De]compressor" /du "https://github.com/google/brotli" /n "Eric Lawrence" /t http://timestamp.digicert.com /fd SHA1 brotli.exe
signtool sign /as /d "Brotli [De]compressor" /du "
https://github.com/google/brotli" /n "Eric Lawrence" /tr http://timestamp.digicert.com /td SHA256 /fd SHA256 brotli.exe

Notably, we sign the file twice:

Windows File Properties show two signatures

First, sign using a SHA1 digest (older Windows versions don’t support SHA256). Then add an additional signature (the /as argument) using the stronger SHA256 file digest (the /fd argument).

For the stronger signature, use /tr to specify the timestamp URL (SHA256 signatures should use RFC3161 timestamps) and request that the timestamping server use a SHA256 digest (the /td argument).

Both signtool invocations will prompt for your PIN to access the private key stored on the token:

Windows PIN prompt

I was somewhat annoyed that the YubiKey only supports an 8 character PIN/password; I later learned that I can use the same 10 character password my old token uses—the final two characters are silently ignored.

After you’ve signed the file, you should use Windows Explorer to verify that each of the signatures and timestamps is valid:

Signature OK

Timestamp Signature OK

Interestingly, most public CAs will use SHA256 for the timestamp’s digest but not for the signature itself; you can see this if you look closely at the timestamp signature (“RSA”):

Just RSA

This is likely due to a limitation in OpenSSL, and isn’t seen in Microsoft’s signatures (“sha256RSA”):

SHA256RSA

A Few Caveats

  • MSIs cannot be dual-signed, only executables. (Update: Possibly introduced in Windows 8? See comments below.)
  • Not all timestamping servers support SHA256 and not all support RFC3161 from their default timestamp service. For GlobalSign, use http://timestamp.globalsign.com. For Comodo, use http://timestamp.comodoca.com/ (details). http://tsa.starfieldtech.com also works.

Getting Started with Profile Guided Optimization

For the convenience of the Windows developer community, I periodically compile the Zopfli and Brotli compressors from source, building for Win32 and code-signing the binaries (Interested? Get Zopfli.exe and Brotli.exe). After announcing the latest build on Twitter, I got an interesting question in reply:

Do you even PGO?

While I try to use the latest compiler (VS2015 U1), I’ve never used PGO with C++ myself. Profile guided optimization requires that you first compile a special instrumented binary that you run against a training set of data. The generated profiling data is fed into the compiler and it compiles an optimized binary based on the observed execution of the code, tuning the hottest paths for speed.

As with any technology-adoption question, I wondered: 1> Is using PGO hard? and 2> Will it noticeably improve performance?

Spoiler alert: The answers are “No” and “Yes.”

I started by skimming this old blog about PGO in Visual Studio; it looks pretty simple.

Optimizing a compressor with PGO is pretty straightforward. Unlike a GUI application with thousands of different operations, a compressor really only does one thing—compress.

I created a folder with files that I felt reasonably represent the types of data that I’ll be compressing with Zopfli (eight files captured via Fiddler). I could’ve experimented using a broader sample, but this seemed like a fine corpus of data with which to begin.

Click Build > Profile Guided Optimization > Instrument to generate an instrumented binary:

Build > Profile Guided Optimization > Instrument

Right-click the project in the Solution Explorer pane and choose Debugging under the Configuration Properties category. Edit the Command Arguments to specify the training scenario. Zopfli accepts a list of files to compress, so we simply list all eight:

Edit Command arguments

Close the dialog and click Build > Profile Guided Optimization > Run Instrumented/Optimized Application to run our application and generate profiling data:

Run Instrumented/Optimized Application

The scenario then runs; it takes a bit of extra time due to the cost of the profiling instructions in the instrumented binary. After it completes, a new file (Zopfli!1.pgc) is written to the \Release\ folder; if we’d run the application multiple times to train different scenarios, Zopfli!2.pgc, Zopfli!3.pgc, etc would be present as well.

Finally, click Build > Profile Guided Optimization > Optimize to generate a new build using the profiling data to select paths for optimization. You can see the effect of the profiling database on the Build in the Output window:

Build output shows optimizations

Now your executable has been optimized.

Pretty simple, right?

Proper benchmarking is an entire field itself, but let’s do the simplest thing that could possibly work to check the effectiveness of the optimizations:

Script runs optimized and unoptimized

We run the script a few times and see that the original unoptimized binary takes ~64 seconds to compress the corpus and the optimized binary takes ~46 seconds, a savings of almost 30%.

ZopFli PGO vs non PGO

You should run the same benchmark against a new set of data, just to ensure that your changes yield similar improvements (or at least no regression!) given different input data. A few runs of my PNGDistill tool (which uses Zopfli internally) show improvements of 10% to 25% when using the optimized compressor.

Pretty cool, right?

-Eric Lawrence

What’s New in Fiddler 4.6.2

TLDR? – Get the newest Fiddler here.

It’s been just over two months since the last significant release, and Fiddler 4.6.2.0 (and v2.6.2.0) are now available.

As always, the latest build includes a slew of bugfixes and minor tweaks, as well as a number of features described in this post.

Default Certificate Generator Changed

Changes coming to certificate validation in browsers and other clients mean that certificates generated by makecert.exe (previously Fiddler’s default generator) will soon be rejected. To address this problem, the default certificate generator on Windows 7 and later has been changed to CertEnroll. (Windows XP and Vista users should consider installing the similar CertMaker Addon).

Unfortunately, if you’re upgrading from an earlier version of Fiddler which used a different certificate generator, you may need to explicitly reset Fiddler’s certificates. Doing so is simple:

  1. Click Tools > Fiddler Options.
  2. Click the HTTPS tab.
  3. Ensure that the text says Certificates generated by CertEnroll engine.
  4. Click Actions > Reset Certificates. This may take a minute.
  5. Accept all prompts
  6. If you are using Fiddler to capture secure traffic from a mobile device or Firefox, you will need to remove the old Fiddler root certificate from that device (or Firefox) and install the newly-generated Fiddler certificate.

If necessary, you can read more about resetting Fiddler’s Certificates or read more about Fiddler’s Certificate Generators.

SAZ Repair

From time to time, users have asked for help with Fiddler Session Archive files (.SAZ or .RAZ files) that are corrupt, either because they are incomplete (e.g. power failed) or they were mangled by an incomplete download or a failing disk drive.

Fiddler 4.6.2 includes a new feature that can recover data from corrupt Session Archive files. If the Session Archive fails to load due to corruption, you’ll be prompted to attempt a repair of the file. Data recovered from the SAZ file will be stored in a new archive and loaded for display.

Notably, this feature may also be useful to recover corrupt .zip, .docx, .xlsx, .pptx, etc files that have nothing to do with Fiddler; give it a try!

FiddlerHook Removed

This release removes the FiddlerHook extension for Firefox. Mozilla is changing their add-on model for Firefox extensions. Short-term, Firefox requires that extensions be signed (and Mozilla has declined to sign FiddlerHook) and over the next year, Mozilla will be removing the XUL Overlay extension model upon which FiddlerHook was based.

Fortunately, you don’t really need FiddlerHook to use Fiddler with Firefox. For HTTP traffic, it will often “just work” and for HTTPS traffic, only minor configuration updates are needed. You can read this post for tips on using Fiddler with Firefox.

Decryption Control

Previously, Fiddler UI only allowed you to exempt certain hosts from HTTPS decryption; if you wanted to only decrypt from a small number of hosts, you were forced to use the script engine. That limitation has been removed via a new option on the Tools > Fiddler Options > HTTPS tab. Simply click the link to toggle between exclusion and inclusion:

imageimage

Extensibility Improvements

This release adds a number of improvements to Fiddler’s extensibility, from both FiddlerScript and .NET extensions.

BindUIButton

You can now add buttons to Fiddler’s toolbar in a supported way. Simply add a new BindUIButton attribute to a static method in your FiddlerScript file; the string argument is the caption with which to label the button.

For instance:

    BindUIButton("Copy HAR")

yields:

toolbar button

Toolbar buttons are added to the left of the toolbar in the order opposite of their listing within the FiddlerScript. Adding images is not supported from FiddlerScript but you can use Unicode Emoji symbols if you’d like.

Fiddler extensions may add to the toolbar using the static method FiddlerToolbar.AddToolstripItem() and may remove entries using .RemoveToolstripItem().

Export to String

In many cases, you may wish to generate a string representing one or more Sessions in either HTTPArchive (HAR) or cURL format. While you can manually use File > Export to generate files of either format, you can now skip the middle-man and export to these types in memory. To do so, simply set the ExportToString option and do not set a Filename option. After the DoExport command completes, the output is found in the OutputAsString option.

For instance, you can add the following to your FiddlerScript:

BindUIButton("Copy HAR")
ContextAction("Copy HAR")
public static function doCopyHar(arrSess: Session[])
{
var oExportOptions = FiddlerObject.createDictionary();

// If you’d prefer to save to a file, set the Filename instead
//oExportOptions.Add(“Filename”, “C:\\users\\lawrence\\desktop\\out1.har”);

oExportOptions.Add(“ExportToString”, “true”);
oExportOptions.Add(“MaxBinaryBodyLength”, 1000000);
oExportOptions.Add(“MaxTextBodyLength”, 1000000);

FiddlerApplication.DoExport(“HTTPArchive v1.2”, arrSess, oExportOptions, null);
var sOutput: String = oExportOptions[“OutputAsString”];

Utilities.CopyToClipboard(sOutput);
FiddlerApplication.UI.SetStatusText(“Copied Sessions as HAR”);
}

…and Fiddler will add a toolbar button and context menu command that copies the Selected Sessions to the clipboard in HAR format. (Tip: You can choose Edit > Paste As Sessions in Fiddler to create new Sessions based on HAR text that you’ve copied from browser tools.)

Alternatively, you can add a similar command to copy the Selected Sessions as a set of cURL commands:

BindUIButton("Copy cURL")
ContextAction("Copy cURL")
public static function doCopyCurl(arrSess: Session[])
{
var oExportOptions = FiddlerObject.createDictionary();

// If you’d prefer to save to a file, set the Filename instead
//oExportOptions.Add(“Filename”, “C:\\users\\lawrence\\desktop\\out1.bat”);

oExportOptions.Add(“ExportToString”, “true”);

  FiddlerApplication.DoExport("cURL Script", arrSess, oExportOptions, null);
var sOutput: String = oExportOptions["OutputAsString"];

Utilities.CopyToClipboard(sOutput);
FiddlerApplication.UI.SetStatusText(“Copied Sessions as cURL”);
}

Invoking on the UI Thread

Fiddler processes Sessions on background threads, but you should only ever manipulate Fiddler’s UI using the UI thread. Only a few of Fiddler’s UI calls are thread-safe; if you’re not sure, your script should use the new FiddlerObject.uiInvoke or FiddlerObject.uiInvokeAsync methods to avoid crashing or corrupting the user-interface.

Load Extensions at Runtime

To support some exciting new work from the community, Fiddler now has the ability to load additional Extensions and Inspectors at runtime; this enables building of more complex add-on systems atop Fiddler’s existing system. To use these APIs, invoke any of these four methods from the UI thread:


FiddlerApplication.oExtensions.InstantiateInspectorsFromPath(string sPathToInspectors)
FiddlerApplication.oExtensions.InstantiateExtensionsFromPath(string sPathToExtensions)
FiddlerApplication.oExtensions.InstantiateExtensionsInFile(FileInfo oFile, bool bWriteToLog, bool bRethrowExceptions)
FiddlerApplication.oExtensions.InstantiateExtensionByType(Type typeExtension, bool bWriteToLog)

Thank You!

Lastly, I’d like to thank everyone for all of your support over the last twelve years, as Fiddler has evolved from a side project to a fully-supported debugging platform used around the world. I’m excited to see where Telerik takes Fiddler next, and while I’ll be keeping plenty busy in my new job, I expect I’ll remain involved in the Fiddler community (updating the book, and haunting the forum) for quite some time.

Wishing you all the best in 2016 and beyond!

-Eric Lawrence

My Next Adventure

Back in 2004, I couldn’t get the tiny IE team interested in fixing caching bugs that were causing my team’s website to break in bizarre and unpredictable ways. I figured I’d hop over there, fix some bugs, and move along. I quickly realized that I was hopelessly in love with browsers in general and security in particular. The hours were long, the problems were immense, but it was easy to make a big difference.

After eight years on the IE team, mostly working in Security, I felt like I’d crafted my dream job. I got to work with smart people every day, and help protect the browsing public from some very bad guys. It was very difficult to leave, but Telerik offered me a different dream job—building my side-project, Fiddler, on a full-time basis.

I spent three years here, doing important work on Fiddler to help take it from a side-project to a professional-caliber tool with the features and polish that users expect. And I’ve had a blast.

Alas…

I’ve missed working on browsers. And on security. While Fiddler has kept me close to that scene, it wasn’t quite close enough. As one of my old leads on the IE team once observed: “No matter what you add to Fiddler, your work on a browser used by almost a billion people will always have a greater impact.”

In the midst of this nostalgic longing, a former colleague posted the following tweet:

Tweet: Join the Chrome Security team

Casual conversations were had. Then more serious conversations. Then interviews. And more interviews.

Philip Su, a brilliant guy whose tech talk inspired me to apply at Microsoft once said: “The team you want to join is the one that’s hard to get into.

Every single person I talked to was smarter than I am. It was crazy-intimidating. And inspiring.

Tweet: Wanna grow? Be the dumbest guy in the room

For my first few years on IE, there was ample speculation that Google would release a browser, presumably some slick skinning of Firefox with all the Google services bolted on. Then Chrome shipped and it was so much more interesting. So many things were done “right” from day 1, and the pace of evolution was amazing. And it wasn’t just the technical guts– I was astonished to see things like the Chrome comic book, which explained things like process isolation and integrity levels in a way that mere mortals could understand. Chrome continued to evolve and grow to take on its role as a platform; ChromeOS now powers a third of the machines in my house. The Chrome team is driving the security of the web as a whole.

I want users to win. To achieve that, I want the web to win, and I want to make life harder for the bad guys every day.

I’m thrilled, excited, honored, and more than a little intimidated to be joining the Chrome Security team on January 4th 2016.

Let the firehose-drinking begin!

Boy being knocked over by a stream of water from a firehose directed at his face

-Eric

Update: I wrote about my experiences after Year One and Year Two.

Segue

My last day at Telerik is December 31st, 2015.

More soon


Here’s a copy of my “Last day” blog post for posterity.

Fiddler—A Segue

 by Eric Lawrence  December 22, 2015 ProductivityDebugging11 Comments

In September 2012, Telerik completed the acquisition of the Fiddler Web Debugger, and I announced that I would join Telerik to upgrade my side project to my full-time job.

It’s been a busy three years, as we evolved Fiddler from version 2.4.1 to 4.6.2—the changelog alone grew by 1701 entries as we added dozens of major features, hundreds of tweaks, and thousands of fixes. Nearly every line has been touched, and performance and functionality have been improved throughout. We brought Fiddler to Linux, simplified running it in a VM on a Mac and worked to ensure that it remains compatible with all of the latest-version mobile platforms and desktop browsers, including Microsoft Edge. I was able to make long-awaited improvements in areas like Image AnalysisWebSocket inspectionAPI TestingextensibilityUI customization, PCAP import and many more. In my off-hours, I even released a Second Edition of my best-selling book “Debugging with Fiddler.” Perhaps most rewarding of all, I had the opportunity to interact with thousands of customers via issue reports, and speak to thousands more at conferences and webinars.

Telerik has honored its commitment to keep Fiddler for Windows available for free, even as we introduced a new fully-supported commercial offering that allows companies to build Fiddler-like functionality into their applications via the FiddlerCore class library.

Behind the scenes, many engineering process improvements were introduced. We migrated from “xcopy-to-NAS source control” to a private repo on GitHub. A Jenkins CI server was introduced to catch build breaks across our many targets (Windows v2, Window v4, FiddlerCore v2, v3, and v4), and we added unit tests for critical functionality. Issue tracking moved from a pile of scrawled napkins to tagged and prioritized GitHub issues, and code-signing was upgraded to use a hardware token.

While I love featuresmore than anything else, it’s these engineering process improvements that give me the confidence that Telerik will be able to continue to improve Fiddler as I move on to pursue an exciting opportunity outside the company in 2016.

I had no idea what I was signing up for when I released the first build of Fiddler almost thirteen years ago—it’s been an incredible adventure, and it’s time for a change. While I expect to remain involved in the Fiddler community via ongoing updates to the Fiddler book, hopping in to answer questions on StackOverflow & the forum and building useful extensions, I’ll pass the development baton to my colleagues at Telerik who have been building indispensable tools and controls for developers since 2002. I’m excited to see what’s coming next—projects like Telerik PlatformTelerik® Kendo UI® and NativeScript all have some pretty fantastic plans for 2016 that I think you’ll enjoy.

Thanks for everything, and happy holidays!

-Eric Lawrence

Certificates Matter

Recently, my web host stopped supporting the FrontPage Server Extensions used by Microsoft Expression Web 4 for website publishing (FPSE is now out-of-support). FPSE allowed me to publish to my site over a HTTPS connection, helping keep my password safe and my uploaded files unmodified.

Unfortunately, the alternative FTP transport is completely insecure–passwords and data transfer in plaintext and can be stolen or tampered and Microsoft products generally don’t support FTPS. As a consequence, I had to stop using Expression Web to edit my various websites. Update: As it turns out, you *can* use FTPS inside Expression Web, but only via the Site > Open Site menu, not the File > Open menu. Expression then warns you that FTP is insecure (bizarrely implying HTTP is better), but network monitoring shows that it’s properly using FTPS under the covers.

Fortunately, my favorite text editor, EditPad Pro offers FTPS support and I quickly moved to using it to edit my site.

Except for one thing—even when using a shared host, the server always returned the same certificate, one whose Subject Name didn’t match the hostname of my website. Yet EditPad didn’t complain at all, it just silently accepted any certificate and sent my username and password. An active man-in-the-middle can easily intercept FTPS connections and return a dummy certificate which EditPad would happily use.

I reported this vulnerability to the developer and I’m happy to see that he’s fixed this problem in version 7.4.0; if the certificate presented isn’t valid for the target, a security prompt is shown every time:

TLS Name Mismatch warning

Ideally, my webhost will start using my installed certificate for FTPS and WebDAV connections, but in the interim manual certificate validation serves as a fallback.

If you build any TLS-protected client or server application, you should always validate the certificate presented during the handshake.

Stay safe out there!

-Eric Lawrence