Download Firefox -  a safer, easier to use web browser. Return to iribbit.net - Leap into the online experience! Return to iribbit.net - Leap into the online experience! iribbit.net - Leap into the online experience!

Project News :.

The latest project to launch was the site for Gorilla Offroad Company. Aside from their main site, a social media strategy was develop to launch the company into various industry specific automobile enthusist discussion board communities as well as popular social media fronts like Facebook, Pinterest, and Twitter.


Valid XHTML 1.0 Transitional

Valid CSS!

Section 508 Compliant

powered by: Macromedia ColdFusion MX

made with: Macromedia Dreamweaver MX

What is RSS

XML - often denotes RSS Feed information.

Macromedia - ColdFusion Programming
white horizontal rule

ColdFusion News :.

To bring a little life to my site, I've pulled a couple What is RSS Feeds into this page. You can currently choose between the technology related news stories from the following news sources:



You are currently viewing and RSS Feed from Pete Freitag's Blog.



Ways to suppress a finding in Fixinator

Code is complex, so any static application security testing (SAST) tool will find things that may not be an actual security issue. Fixinator has a few different ways we can deal with this problem. For example, let's suppose you have a variable application.maxstories=10 set in Application.cfc, and you use that variable in a different file like this:

<cfquery name="news">
SELECT headline, story 
FROM news
ORDER BY date_published DESC
LIMIT #application.maxstories#
</cfquery>

Assuming that application.maxstories is always defined, this query isn't vulnerable to SQL injection because you can't change the value of application.maxstories unless you can change the application source code.

Quick aside: If the application.maxstories variable is defined conditionally, then it is a different story. The value of the variable in the query could be manipulated via something I call scope injection via url.application.maxstories for example. But that depends on application.maxstores being undefined.

Suppressing a single finding with Fixinator

If you are using Fixinator then we have a few different ways to suppress this finding. We can add a comment as such:

<cfquery name="news">
SELECT headline, story 
FROM news
ORDER BY date_published DESC
<!--- ignore:sqlinjection because application.maxstories is always defined --->
LIMIT #application.maxstories#
</cfquery>

When Fixinator finds an issue, it will check to see if there is a comment with the pattern ignore:scanner-type directly above or on the same line as the issue. You can optionally add a reason to the comment, which I always like to do.

However if this were my code, I would rather just do this:

LIMIT #int(application.maxstories)#

Fixinator understands that wrapping a variable with int() is a safe solution. I prefer that approach over a comment.

Suppressing a type of finding over many files with Fixinator

Fixinator has a setting called ignorePatterns that can be defined in a .fixinator.json file. For the above example, we might use something like this:

{
  "ignorePatterns": {
    "sqlinjection": ["application.maxstories"]
  }
}

That will tell fixinator to ignore any SQL Injection finding where the variable contains application.maxstories, pretty handy way to keep your fixinator report free of any false positives.

Here's another example... let's assume we fixed XSS issues in our app before the encodeForHTML was builtin to CF by creating our own function called xssEncoder. Perhaps our own function originally called ESAPI directly via java, but now is just an alias to encodeForHTML. This abstraction isn't a bad thing, it even allows us to switch to a different encoder in the future if a better one comes along. We can tell Fixinator about it like this:

{
  "ignorePatterns": {
    "sqlinjection": ["application.maxstories"],
    "xss": ["xssEncoder("]
  }
}

Of course you have to be careful about what you ignore, but I think it is an important feature to have. Without a good way to manage false positives you are either giving developers pointless work just to please the scanner, or the reports are full of false positives and end up being ignored. Neither lead to better security.


(Thu, 08 Sep 2022 20:49:00 GMT)
[view article in new window]

Simple Parallel Execution in ColdFusion or Lucee

A really handy feature of the arrayEach() function is the parallel argument. It has been supported in Lucee since 4.5, but ColdFusion 2021 now supports it as well.

What does the arrayEach function do?

Quite simply it loops over each element of an array and invokes a function for each element of the array, here's a simple example:

fruit = ["Apples", "Oranges"];
arrayEach(fruit, function(item) {
    writeOutput("I like #item#
"); });

It would output (run on trycf):

I like Apples
I like Oranges

Make it parallel

Recently on the cfml slack the question was asked:

Anybody have a good examples of using the parallel features or multi-threading <cfhttp> requests?

Yes, you can do this with the parallel argument of array each quite easily:

requests = [
  {"url"="https://httpbin.org/ip"},
  {"url"="https://httpbin.org/uuid"},
  {"url"="https://httpbin.org/uuid"},
  {"url"="https://httpbin.org/uuid"},
  {"url"="https://httpbin.org/uuid"}
];
maxThreads = 5;
parallel = true;

tick = getTickCount();

arrayEach(requests, function(value, index) {
  var httpResult="";
  cfhttp(url=value.url, result="httpResult");
  value.result = httpResult.fileContent;
}, parallel, maxThreads);

writeOutput("

Took: #getTickCount()-tick# with parallel: #parallel#, maxThreads: #maxThreads#

"); writeDump(requests);

You can run the example on trycf and see that when parallel = true; it runs in about 180ms, when you set parallel = false; it takes 750ms.

Pretty simple way to get a big speed boost for that use case, and much easier than using cfthread.

Things to look out for

One thing you do need to be careful of when you start multithreading is synchronization issues. In my example I am updating the array element struct, but if I were modifying the array itself, or another shared variable within my closure function, I would need to use cflock.

For the same reasons, if you create any variables within your closure function, make sure they are var scoped or you will run into some strange issues. Without the var scope, the variable will be in the variables scope and shared among all the iterations.


(Wed, 31 Aug 2022 20:07:00 GMT)
[view article in new window]

Creating a ColdFusion UUID in MySQL

The uuid() function in MySQL returns a 36 character hex string, formatted as:

aa479ea9-1d9d-11ed-ba03-564760fe47b7

ColdFusion's createUUID() function returns a 35 character hex string formatted as:

AA479EA9-1D9D-11ED-BA03564760FE47B7

Both store the same amount of data (16 bytes), the only difference is that there is an extra dash in the MySQL uuid() function result.

Here's some SQL I came up with to create a UUID using ColdFusion's formatting in raw SQL:

SELECT upper(concat(left(uuid(), 23), right(uuid(), 12)))

It is not an ideal solution because I am actually calling uuid() twice, but it is sufficient for my use case. You could probably use a regex to remove the extra dash and avoid calling uuid twice if you wanted to try and optimize it. Feel free to post a comment if you can come up with a better way to do it.

Now suppose you want to convert the CFML uuid back to a MySQL uuid, you can do so like this:

SELECT lower(concat(left(some_id, 23), '-', right(some_id, 12))) FROM table

(Wed, 17 Aug 2022 01:59:00 GMT)
[view article in new window]

Better CFML Code with CI

I gave a presentation for the Adobe ColdFusion Developer Week Conference today titled: Better CFML Code with CI. You can find the slides for my talk here, and the video here.

Here is a link to the code samples.


(Wed, 20 Jul 2022 00:16:00 GMT)
[view article in new window]

Firefox Hosts File Not Working?

I'm probably not the first one to notice this, but if you have a hosts file (eg /ect/hosts or c:\windows\system32\drivers\etc\hosts on windows) you might find that recent versions of Firefox will ignore it. When I encountered this, my guess was that it was caused by Firefox enabling DNS over HTTPS by default.

And it turns out that you can workaround this issue by disabling DNS over HTTPS in Firefox.

How to Disable DNS over HTTPS in Firefox

  • Open Firefox Settings
  • Open Network Settings (on bottom of General tab or just type dns in the search box)
  • Uncheck the Enable DNS over HTTPS checkbox

After making this change your hosts file dns names should now resolve properly.

What are the implications of disabling DNS over HTTPS?

Instead of using the DNS server that your operating system / network settings provide, firefox will make a HTTPS request to a DNS server. By default it routes these requests to CloudFlare DNS (via https://1.1.1.1/dns-query - this has some pros and cons.

What is good about DNS over HTTPS? Well, your DNS traffic is not usually encrypted by default, so that means that your ISP can and probably does log and sell the DNS request history to third parties. With this data the ISP could know what websites you request. The ISP could also learn this from the network traffic based upon which IPs you are connecting to, but the DNS data may be richer. With DNS over HTTPS the host name that you are requesting is encrypted in the HTTPS request, so now only the endpoint server (for example CloudFlare DNS) would have access to the host names you are visiting. According to CloudFlare Unlike most DNS resolvers, 1.1.1.1 does not sell user data to advertisers

The cons of DNS over HTTPS, if you are on a corporate network you may run into similar issues if there are dns records that only resolve to your DNS server, you might also have a DNS server you want to use for blocking / filtering purposes and the DNS over HTTPS setting would bypass that protection. These cases are less common, so enabling the DNS over HTTPS generally is a good default.

Example DNS Over HTTPS Query

Here's how you can make a DNS over HTTPS query using curl from the commandline:

curl --http2 -H 'accept: application/dns-json' 'https://1.1.1.1/dns-query?name=firefox.com'

And that will return with something like this:

{
  "Status": 0,
  "TC": false,
  "RD": true,
  "RA": true,
  "AD": false,
  "CD": false,
  "Question": [
    {
      "name": "firefox.com",
      "type": 1
    }
  ],
  "Answer": [
    {
      "name": "firefox.com",
      "type": 1,
      "TTL": 296,
      "data": "44.236.72.93"
    }
  ]
}

(Wed, 13 Jul 2022 21:21:00 GMT)
[view article in new window]

How to read a ColdFusion Stacktrace

This question came up recently:

How do you read a stack trace? Are there any resources that will educate me?

While there are many resources specific to Java on reading a stacktrace, I don't think there are many related to ColdFusion or CFML. So let's make one here.

Here's a part of a stacktrace that this particular user was wanting to understand better:

lucee.runtime.exp.NativeException: invalid hexadecimal String
 	at lucee.runtime.coder.HexCoder.decode(HexCoder.java:62)
 	at lucee.runtime.coder.Coder.decode(Coder.java:61)
 	at lucee.runtime.coder.Coder.decode(Coder.java:47)
 	at lucee.runtime.crypt.Cryptor.decrypt(Cryptor.java:194)
 	at lucee.runtime.functions.other.Decrypt.invoke(Decrypt.java:66)
 	at lucee.runtime.functions.other.Decrypt.call(Decrypt.java:45)
 	at cfc.utils.security_cfc$cf$w.udfCall(/cfc/utils/security.cfc:25)
 	at lucee.runtime.type.UDFImpl.implementation(UDFImpl.java:106)
 	at lucee.runtime.type.UDFImpl._call(UDFImpl.java:344)
 	at lucee.runtime.type.UDFImpl.call(UDFImpl.java:217)

Step 1: Start at the Top

The first line of the stacktrace will usually be formatted as type: message, the type is going to be the name of a java class that holds information about the exception, in this case it is lucee.runtime.exp.NativeException. In this case it is a Lucee server, but all the same ideas apply on a ColdFusion server. The message will hopefully give you a summary of what the actual problem is. Now I say hopefully, because this depends on how good the exception handling code is, we've all written a vague error message.

Step 2: Look for a cfm or cfc file

Next I work my way down the stacktrace starting at the top, looking for a cfm or cfc file. This tells me where in my code the exception originated from. If you can't find a cfm or cfc file, then it could be that the exception happened outside the context of your code (for example it could be thrown from Tomcat or ColdFusion or Lucee, etc before or after your code runs). In this example stacktrace we see a line:

at cfc.utils.security_cfc$cf$w.udfCall(/cfc/utils/security.cfc:25)

So now we can take a look at our code security.cfc and go to line 25, in this case it was:

decrypt(trim(ucase(arguments.inputString)), eKey, "AES","hex")

That tells us it was the decrypt function call, but we can see that by looking at the line above this line in the stacktrace. That is useful because there are a few CFML functions being called on that line of code, trim, ucase and decrypt, but we know from the stracktrace that the exception happened in the decrypt call.

In some cases you might want to keep going down the stacktrace and look for another CFML line, but you don't always need to look at the bottom of the stacktrace, usually the most important parts are at the top.

Step 3: Work back up the stacktrace

We can see how execution is traveling between several java functions calls once we call the decrypt function, all the way up to the second line of the stracktrace. The line:

at lucee.runtime.coder.HexCoder.decode(HexCoder.java:62)

This tells us that the class lucee.runtime.coder.HexCoder in the method call decode() on line 62 is where the exception was thrown from. Because lucee is open source, we can actually take a look at the actual code that threw the exception:

if ((hexa.length() % 2) != 0) {
    throw new CoderException("invalid hexadecimal String");
}

From that code we can tell that the length of the hex string passed in was an odd number!

If you want to play around with reading a stacktrace, here's an example on TryCF that you can play around with. In that example there are multiple function calls that you can follow the execution through.


(Thu, 23 Jun 2022 22:41:00 GMT)
[view article in new window]

How I cut AWS Lambda Java Cold Start Times in Half

It is rare that a simple JVM argument change can have a dramatic impact on execution times, but in the case of AWS Lambda adjusting the Tiered Complication settings can have a really big impact on performance in many (but not all) cases.

The change I made was to add the JVM arguments:

-XX:+TieredCompilation -XX:TieredStopAtLevel=1

On AWS Lambda you can do this by simply adding the environment variable:

JAVA_TOOL_OPTIONS = -XX:+TieredCompilation -XX:TieredStopAtLevel=1

This chart below shows the average execution time of a Java (more specifically written in CFML and using FuseLess) Lambda Function over the course of two days. I've annotated where I made the change and you can see average execution times cut in half, cold start times also cut in half (though the chart doesn't show that). Before enabling the flag I was seeing cold start times of about 3.6 seconds, after the flag average cold start time was around 1.2 seconds.

Chart of average lambda execution time before and after jvm change

Note that this particular java lambda function that I used for testing does have some highly intensive invocations that might take up to 30 seconds to execute, after the change I didn't see any executions going above 15 seconds.

What is TieredCompilation and what is TieredStopAtLevel?

That graph is probably leading you to wonder what is TieredCompilation in java. As you may know the JVM translates your bytecode (class files) into machine code at runtime. This step can take a lot of resources if the compiler wants to make it optimal, it might add counters so it can figure out where the hot spots are and then perform further optimizations. This works great and leads to awesome performance on the JVM when your server is running for a long time. In a way the JVM self tunes itself over time, at runtime.

When you are running on a serverless environment like AWS Lambda your runtime will only survive for a short period of time (as little as a few minutes, but no more than a few hours) before being destroyed. The assumption that the JVM default configuration makes is servers will run for a long time, and it should optimize the parts of the code that run the most over time. By setting the TieredStopAtLevel flag to 1 we are telling the JVM not to insert profiling code that is used for runtime measurements and optimizations. In essence we are telling the JVM, don't try to be too smart, don't optimize for the future - this code may never run agin, just execute the code, and in the process we are saving CPU cycles and yielding faster execution.

I learned about this technique from AWS, so it makes me wonder why they don't just enable it by default on all Java Lambda Functions? I think all Java Lambda functions could see a lower cold start time with these flags set, but possibly not a lower overall average execution time like I saw. It really depends on how well your code can be optimized by the jvm, and how many executions run before the lambda container is recycled. It is certainly worth your time to experiment and see if this flag will improve your Java Lambda Cold Start and Average Duration execution times. Such large performance gains are often not so easily found.

While my experience was specific to AWS Lambda running Java, I'm sure if you are running Azure Cloud Functions on Java, or Google Cloud Functions on Java you could use the same tip to cut your cold start times and hopefully your average duration as well.

Other ways to improve Java Cold Start Times

  • Deployment Size - I've found that the total size of your deployment can make a big difference in the Java Cold Start execution time. Going from a 50mb deployment zip to a 15mb zip can make a big difference. Upon Cold Start, Lambda has to download your zip from the network, and then extract the zip to the file system.
  • RAM - Increasing the amount of RAM that your Java Lambda has will reduce the ColdStart time, for Java I think the Lambda should have at least 1GB of memory (I usually run around 2-3GB). But it's not just about the RAM, because increasing the RAM will also give the Lambda instance more CPU power, which is helpful on Cold Starts.
  • Avoid Nested Jars - Avoid nesting jars within jars within jars if you can. This is just creating busy work for the CPU to extract upon cold start.

(Thu, 07 Apr 2022 20:56:00 GMT)
[view article in new window]

Spring4Shell and ColdFusion

I've had a bunch of people ask me if ColdFusion / Lucee servers need to worry about the recent Java vulnerability in Spring, nick named Spring4Shell, or more formally known as CVE-2022-22965.

To the best of my knowledge ColdFusion and Lucee do not make use of the Java Spring Framework by default, and do not include any of the vulnerable Spring jars by default. Disclaimer: I haven't done an exhaustive analysis, and I haven't checked every single version of ColdFusion or Lucee.

I used JFrog's Spring Tools scanner to scan both a ColdFusion 2021 and a Lucee 5.3 installation, neither returned any findings.

According to Spring's blog entry about this issue you may be impacted if you are:

  • Running on JDK 9 or higher
  • Apache Tomcat as the Servlet container.
  • Packaged as a traditional WAR and deployed in a standalone Tomcat instance. Typical Spring Boot deployments using an embedded Servlet container or reactive web server are not impacted.
  • spring-webmvc or spring-webflux dependency.
  • Spring Framework versions 5.3.0 to 5.3.17, 5.2.0 to 5.2.19, and older versions.

Most ColdFusion Servers would be running JDK 9 or higher, and Apache Tomcat, but probably do not have the spring-webmvc or spring-webflux dependency.

I have had some people tell me FuseGuard was catching some Spring4Shell exploit attempts. You might see FuseGuard's Scope Injection Filter block requests that look like this:

form.CLASS.MODULE.CLASSLOADER.RESOURCES.CONTEXT.PARENT.PIPELINE.FIRST.PATTERN

(Thu, 07 Apr 2022 02:36:00 GMT)
[view article in new window]

Order by NULL Values in MySQL, Postgresql and SQL Server

If you have a column that may contain NULL values, and you want sort on that column with an ORDER BY clause, which comes first the null values or the non null values?

This is something that I have to look up, or simply test each and every time I need to know, so I figured it would be good material for a blog entry.

NULL Values First on MySQL or PostgreSQL

If you want the columns with null values to show up first, then sort ascending.

SELECT * FROM orders
ORDER BY date_shipped ASC

This would show orders that have not shipped first, and then the orders sorted by date_shipped ascending.

NULL Values Last on MySQL or PostgreSQL

If you want the NULL values to show up after column values, use a DESC sort direction in your order by clause:

SELECT * FROM orders
ORDER BY date_shipped DESC

This query would show the most recently shipped orders first, and orders that have not shipped yet would be last.

Here's a DB Fiddle so you can run the above example on MySQL or PostgreSQL.

SQL Server works the Opposite

Now, I found that SQL Server actually will sort the opposite way, and put the null values first when you sort ascending, and the null values last when you sort descending. Interesting, but also something to be aware of if you are trying to write cross database SQL.

Null Sorting by Database Engine

MySQLPostgreSQLSQL Server
NULL Values FirstASCASCDESC
NULL Values LastDESCDESCASC

(Thu, 10 Mar 2022 23:03:00 GMT)
[view article in new window]

CloudFlare Authenticated Origin Pulls on Nginx or Apache

If you are using CloudFlare in front of your web server, it is a good idea to setup CloudFlare Authenticated Origin Pulls. When this is enabled and properly configured only CloudFlare will be able to connect to your origin web server directly.

An example setup on nginx might require that you add something like this:

ssl_client_certificate /etc/cloudflare/cloudflare-origin-pull-ca.pem;
ssl_verify_client on;    

On Apache it might look like this:

SSLVerifyClient require
SSLVerifyDepth 1
SSLCACertificateFile /etc/cloudflare/cloudflare-origin-pull-ca.pem

In both examples I'm referencing a file: /etc/cloudflare/cloudflare-origin-pull-ca.pem this is CloudFlare's CA Certificate which you can grab from their site here. This public CA certificate is used to sign the client certificate on CloudFlare's edge servers that is used when requesting your origin server. The ssl_verify_client on or SSLVerifyClient require instruct your web server to reject any connections that are not signed by the CA certificate.

While it is pretty straight forward to setup if you miss something you might see a 400 Bad Request error like this:

400 Bad Request
No required SSL certificate was sent
nginx

Here are some things you can check if you see that error:

  • Make sure you have checked the Authenticated Origin Pulls checkbox in CloudFlare Dashboard under SSL/TLS then Origin Server.
  • Make sure you have set your SSL/TLS encryption mode to "Full" or "Full (Strict)" in the CloudFlare Dashboard, it won't work if your encryption mode is set to Flexible or Off.
  • Make sure you have restarted or reloaded the configuration on your web server

(Fri, 28 Jan 2022 00:46:00 GMT)
[view article in new window]


© The connection to the FREITAG's RSS feed has timed out - please try again later. We are sorry for any inconvenience this may have caused.