Publishers of technology books, eBooks, and videos for creative people

Home > Articles > Web Design & Development > Adobe ColdFusion

This chapter is from the book

Implementing Security

ColdFusion provides two ways to secure the functionality that you encapsulate in a ColdFusion component: roles-based authorization, and access control. Chapter 61, "Understanding Security," in Vol. 3, Advanced Application Development, discusses application user authentication and authorization, which allows the assignment of roles to your application's users. This roles-based security can also be applied to the functions in a CFC. The second technique, access control, was used in the preceding chapter in every cffunction tag as the attribute access="...".

Implementing Access Control

The access attribute of the <cffunction> tag basically answers the question, "Who can use this function?" The attribute has four options: private, package, public (the default), and remote. These four options represent, in that order, the degree of openness of the function.

The access options range from a narrow group of potential consumers to a very broad audience. The consumers allowed by each option are as follows:

  • Private. Only other functions within the same CFC can invoke the function.
  • Package. Only components in the same package can invoke the function.
  • Public. Any CFML template or CFC on the same server can invoke the function.
  • Remote. Any CFML template or CFC on the same server can invoke the function, as can Adobe Flash applications (using Flash Remoting) and Web Services clients.

Within any given CFC, you can have functions of any type mixed together. Remember, it's the function and not the component itself to which you grant or deny access.

Let's take a look at each access option to see how they can be used.

Private

I was at a hotel one weekend and passed by a room from which drifted some terrific music and the sound of laughing, happy people. Naturally I wanted to see what the occasion was and join in the festivities. At the door, though, I was met by a gruff and rather large gentleman who blocked my way and shook his head. He pointed to a small sign on a brass post that read "Private Function."

Silly story, but you see the connection. Private functions are the most "exclusive." Any consumer (that is, a CFML page, Web service client, Flash application, and so on) outside of a CFC cannot use a function that has been designated as access="private". Private functions are for use only in the CFC where they are coded. How can they be used at all, then, you ask? They are used by other functions in the same CFC. Generally, private functions are functions whose only purpose is to help other functions. In Chapter 26, FilmRotationCFC had a number of private functions: for example, randomizedFilmList and currentFilmID. Neither of these functions would ever be accessed directly from outside of the component. Rather, they are called from other functions, as we saw with the getCurrentFilmID method. We should mark them private, because they are only used internally to the CFC, and by exposing them to the outside world we risk letting people in on our implementation.

Why bother? You should always hide as much information about implementation as you can. Hiding information gives you the flexibility to change the component's implementation at a later time, due to changed requirements or developing a better algorithm. It also protects the user from changes in your implementation, because code can become dependent on functionality that was never intended to be exposed, and break when it changes. Marking the code private forces your CFC's users to play by your rules when using it.

Now, here's something to watch out for: If you try to invoke a private function from anywhere but inside the component itself, you'll get an error that says "The method 'myPrivateFunction' could not be found in component (whatever)." You'll then think that you typed the name wrong, and go back and check and reenter your code, and still get the same error. "But I can see the function right there! How can it not be found?!?" you'll cry to the heavens. You've not lost your mind—it's just a private function. To be certain, look at the self-documenting view of the CFC in a browser. You'll see an asterisk next to the function's name: "aPrivateFunction*". Then, under the methods list at the top of the page, you'll see a teeny explanation: *private method.

Package

Earlier in this chapter, you saw how component packages could help you organize the components in an application. Likewise, access="package" can help you control the access to your component's functionality within applications. A primary use of package access can be to prevent applications that happen to have functions with the same name from accidentally calling each other.

For example, Orange Whip Studios uses an application that lets the catering department order sandwiches for the movie shoots. A component in this application has a method that adjusts the number of sandwiches needed for a given day. The studio also uses a casting department application that can hire and fire actors. In that application, there is a component that helps calculate staff levels and make the firing decisions. Both of these methods have the apt but far-from-original name of updateQuantity. Without access control at the package level, someone developing an application could inadvertently end up firing 300 actors and leaving the remaining ones very hungry.

Public

The default option for a function's access setting is public. It's a somewhat confusing term, in that it doesn't mean "Anyone in the public can use this function." People who mistake the meaning of public usually find themselves coming to the assumption, "I don't want this function to be available as a Web service, so I shouldn't make it publicly accessible. It's just for my application, so I guess that would make it a private function." They then code a page somewhere that tries to invoke that function, and they get the less-than-intuitive error type that was mentioned earlier for private access: "The method (whatever) could not be found."

Public really means "accessible by the ColdFusion server in which the component is running." So any other component can invoke the function, as can any CFML page.

Here again, those people who cannot use a public function are precisely those you would ordinarily consider to be the "public"—other people on the Internet somewhere trying to use a Web service, for example.

Watch out for HTTP and form posts and public functions. Because the page that you post to happens to be on the same machine as the component that it invokes, many people think that posting a form to a public function should work. But a form post, just like a URL invocation, uses HTTP—it does not access the function from within the server. An HTTP request is just like any other remote request and thus necessitates the most open access option, remote.

Remote

A remote function is what you might have thought a public function is. It's open to anyone who wants it—the whole "public." The function can be used by the same component, another component (regardless of the package in which it's placed), any CFML page (on the server), HTTP requests, Web Services clients, and Adobe Flash applications.

To sum up, you can see how a lack of attention to the access attribute of a function can cause lots of trouble. A function that performs some sensitive business function could be inadvertently made available to the whole world if it were set as remote instead of private. Likewise, a business partner who tries to consume a Web service from your application may not find it in the WSDL ColdFusion creates for your component if you forgot to set the function's access to remote. (Refer to Chapter 68 in Vol. 3, Advanced Application Development, for more information on creating Web services and WSDL with ColdFusion.)

Implementing Role-Based Security in CFCs

In some applications, you'll want to control access to a component's functions based on who is using your application. This will be most common in traditional, HTML-based user interface applications, but it may also be true of Adobe Flash applications. Role-based security is not, however, a common approach to securing access to Web services, since a Web service client is a program and not an individual.

To see this technique in action, let's go back to the actors component that was created earlier in this chapter—the one that retrieves information about all actors. Part of the Orange Whip Studios Web application allows studio executives to review the salaries of the stars—how much should the studio expect to fork over for their next box-office smash? Of course, this information is not exactly something that they want just anybody seeing.

First we need to create the basic security framework for this part of the application, with the security tags in ColdFusion: <cflogin>, <cfloginuser>, and <cflogout>. (We discuss this process in detail in Chapter 23, "Securing Your Applications," online.)

For the purposes of this exercise, we'll just test by running the cfloginuser tag with the role we want to test with:

<cfloginuser name="Test" password="dummy" roles="Producers">

Any roles for the logged-in user will be the roles that correspond to those listed in our component function—more on this after we create the function (Listing 27.5).

The function will be simple: It takes an Actor ID as an argument, queries that actor's salary history, and returns a recordset. Notice, though, that the roles attribute in the <cffunction> tag has a comma-delimited list of values. Only users who have authenticated and been assigned one or more of those roles will be allowed to invoke the method.

Listing 27.5. actor.cfc—The Salary Method

<!--- Demonstrate roles --->
<cffunction name="getActorSalary" returnType="query" roles="Producers, Executives">
  <cfargument name="actorID" type="numeric" required="true"
    displayName="Actor ID" hint="The ID of the Actor">
  <cfquery name="salaries" dataSource="ows">
    SELECT Actors.ActorID, Actors.NameFirst, Actors.NameLast,
      FilmsActors.Salary, Films.MovieTitle
    FROM Films
    INNER JOIN (Actors INNER JOIN FilmsActors
     ON Actors.ActorID = FilmsActors.ActorID)
       ON Films.FilmID = FilmsActors.FilmID
    WHERE Actors.ActorID = #Arguments.actorID#
  </cfquery>
  <cfreturn salaries>
</cffunction>

The roles assigned to this function are Producers and Executives—they don't want any prying eyes finding this sensitive data. All we need now, then, is a page to invoke the component—something simple, as in Listing 27.6.

Listing 27.6. showSalary.cfm—Show Salary Page

<!---
  showSalary.cfm
  Demonstrate CFC roles
  Modified by Ken Fricklas (kenf@fricklas.com)
  Modified: 8/17/2007
--->
<HTML>
<HEAD>
<TITLE>What were they paid?</TITLE>
</HEAD>

<BODY>
<!--- Make sure they are logged in. Change roles to "User" to see what happens if
they don't have sufficient access. --->
<cfloginuser name="Test" password="dummy" roles="Producers">
<!--- Invoke actors component. getActorSalary method will fail unless
  they have sufficient access. --->
<cfinvoke
 component="actor"
 method="getActorSalary"
 returnVariable="salaryHistory">
  <cfinvokeargument name="actorID" value="17"/>
</cfinvoke>
<h1>Salaries of our stars...</h1>
<cfoutput>
<H2>
#salaryHistory.NameFirst# #salaryHistory.NameLast#</H2>
<cfloop query="salaryHistory">
  #MovieTitle# - #dollarFormat(Salary)#<BR>
</cfloop>
</cfoutput>
</BODY>
</HTML>

ColdFusion now has all it needs to control the access to the component. The process will work in this order:

  1. The Show Salary page is requested by a browser.
  2. The <cfinvoke> tag is encountered, specifying the Actor component and the getActorSalary method.
  3. An instance of the component is created, and the function is found.
  4. Since the function has values specified in the roles attribute, a comparison is automatically made between the values in the roles attribute of the <cffunction> tag and those in the roles attributes that were set in the <cfloginuser> tag. If the user is not logged in, this function will fail.
  5. A match will allow the function to be executed as usual; a failure will cause the following error: "Error Occurred While Processing Request—The current user is not authorized to invoke this method."

Notice that an unauthorized attempt to execute a secured function causes ColdFusion to throw an error. Consequently, you should put a cftry around any code that invokes secured functions (Listing 27.7).

Listing 27.7. showSalary_final.cfm—Catching a Secure Function Invocation

<!---
  showSalary_final.cfm
  Demonstrate CFC roles
  Modified by Ken Fricklas (kenf@fricklas.com)
  Modified: 8/17/2007
--->
<HTML>
<HEAD>
<TITLE>What were they paid?</TITLE>
</HEAD>

<BODY>
<!--- Make sure they are logged in. Change roles to "User" to see what happens if
they don't have sufficient access. --->
<cfloginuser name="Test" password="dummy" roles="Producers">
<!--- Invoke actors component. getActorSalary method will fail unless
  they have sufficient access. --->
<cftry>
  <cfinvoke
    component="actor"
    method="getActorSalary"
    returnVariable="salaryHistory">
    <cfinvokeargument name="actorID" value="17"/>
  </cfinvoke>
  <cfcatch>
    What? Trying to steal company secrets? Get lost!
    <cfabort>
  </cfcatch>

<h1>Salaries of our stars...</h1>
<cfoutput>
<H2>
#salaryHistory.NameFirst# #salaryHistory.NameLast#</H2>
<cfloop query="salaryHistory">
  #MovieTitle# - #dollarFormat(Salary)#<BR>
</cfloop>
</cfoutput>
</BODY>
</HTML>

This is not the only way to secure component functionality, of course. You could use the isUserInRole() function to check a user's group permissions before even invoking the function, or you could use Web server security for securing the CFML files themselves. The role-based security in CFCs is, however, a good option particularly if you are already using the ColdFusion authentication/authorization framework in an application.

Peachpit Promotional Mailings & Special Offers

I would like to receive exclusive offers and hear about products from Peachpit and its family of brands. I can unsubscribe at any time.

Overview


Pearson Education, Inc., 221 River Street, Hoboken, New Jersey 07030, (Pearson) presents this site to provide information about Peachpit products and services that can be purchased through this site.

This privacy notice provides an overview of our commitment to privacy and describes how we collect, protect, use and share personal information collected through this site. Please note that other Pearson websites and online products and services have their own separate privacy policies.

Collection and Use of Information


To conduct business and deliver products and services, Pearson collects and uses personal information in several ways in connection with this site, including:

Questions and Inquiries

For inquiries and questions, we collect the inquiry or question, together with name, contact details (email address, phone number and mailing address) and any other additional information voluntarily submitted to us through a Contact Us form or an email. We use this information to address the inquiry and respond to the question.

Online Store

For orders and purchases placed through our online store on this site, we collect order details, name, institution name and address (if applicable), email address, phone number, shipping and billing addresses, credit/debit card information, shipping options and any instructions. We use this information to complete transactions, fulfill orders, communicate with individuals placing orders or visiting the online store, and for related purposes.

Surveys

Pearson may offer opportunities to provide feedback or participate in surveys, including surveys evaluating Pearson products, services or sites. Participation is voluntary. Pearson collects information requested in the survey questions and uses the information to evaluate, support, maintain and improve products, services or sites; develop new products and services; conduct educational research; and for other purposes specified in the survey.

Contests and Drawings

Occasionally, we may sponsor a contest or drawing. Participation is optional. Pearson collects name, contact information and other information specified on the entry form for the contest or drawing to conduct the contest or drawing. Pearson may collect additional personal information from the winners of a contest or drawing in order to award the prize and for tax reporting purposes, as required by law.

Newsletters

If you have elected to receive email newsletters or promotional mailings and special offers but want to unsubscribe, simply email ask@peachpit.com.

Service Announcements

On rare occasions it is necessary to send out a strictly service related announcement. For instance, if our service is temporarily suspended for maintenance we might send users an email. Generally, users may not opt-out of these communications, though they can deactivate their account information. However, these communications are not promotional in nature.

Customer Service

We communicate with users on a regular basis to provide requested services and in regard to issues relating to their account we reply via email or phone in accordance with the users' wishes when a user submits their information through our Contact Us form.

Other Collection and Use of Information


Application and System Logs

Pearson automatically collects log data to help ensure the delivery, availability and security of this site. Log data may include technical information about how a user or visitor connected to this site, such as browser type, type of computer/device, operating system, internet service provider and IP address. We use this information for support purposes and to monitor the health of the site, identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents and appropriately scale computing resources.

Web Analytics

Pearson may use third party web trend analytical services, including Google Analytics, to collect visitor information, such as IP addresses, browser types, referring pages, pages visited and time spent on a particular site. While these analytical services collect and report information on an anonymous basis, they may use cookies to gather web trend information. The information gathered may enable Pearson (but not the third party web trend services) to link information with application and system log data. Pearson uses this information for system administration and to identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents, appropriately scale computing resources and otherwise support and deliver this site and its services.

Cookies and Related Technologies

This site uses cookies and similar technologies to personalize content, measure traffic patterns, control security, track use and access of information on this site, and provide interest-based messages and advertising. Users can manage and block the use of cookies through their browser. Disabling or blocking certain cookies may limit the functionality of this site.

Do Not Track

This site currently does not respond to Do Not Track signals.

Security


Pearson uses appropriate physical, administrative and technical security measures to protect personal information from unauthorized access, use and disclosure.

Children


This site is not directed to children under the age of 13.

Marketing


Pearson may send or direct marketing communications to users, provided that

  • Pearson will not use personal information collected or processed as a K-12 school service provider for the purpose of directed or targeted advertising.
  • Such marketing is consistent with applicable law and Pearson's legal obligations.
  • Pearson will not knowingly direct or send marketing communications to an individual who has expressed a preference not to receive marketing.
  • Where required by applicable law, express or implied consent to marketing exists and has not been withdrawn.

Pearson may provide personal information to a third party service provider on a restricted basis to provide marketing solely on behalf of Pearson or an affiliate or customer for whom Pearson is a service provider. Marketing preferences may be changed at any time.

Correcting/Updating Personal Information


If a user's personally identifiable information changes (such as your postal address or email address), we provide a way to correct or update that user's personal data provided to us. This can be done on the Account page. If a user no longer desires our service and desires to delete his or her account, please contact us at customer-service@informit.com and we will process the deletion of a user's account.

Choice/Opt-out


Users can always make an informed choice as to whether they should proceed with certain services offered by Adobe Press. If you choose to remove yourself from our mailing list(s) simply visit the following page and uncheck any communication you no longer want to receive: www.peachpit.com/u.aspx.

Sale of Personal Information


Pearson does not rent or sell personal information in exchange for any payment of money.

While Pearson does not sell personal information, as defined in Nevada law, Nevada residents may email a request for no sale of their personal information to NevadaDesignatedRequest@pearson.com.

Supplemental Privacy Statement for California Residents


California residents should read our Supplemental privacy statement for California residents in conjunction with this Privacy Notice. The Supplemental privacy statement for California residents explains Pearson's commitment to comply with California law and applies to personal information of California residents collected in connection with this site and the Services.

Sharing and Disclosure


Pearson may disclose personal information, as follows:

  • As required by law.
  • With the consent of the individual (or their parent, if the individual is a minor)
  • In response to a subpoena, court order or legal process, to the extent permitted or required by law
  • To protect the security and safety of individuals, data, assets and systems, consistent with applicable law
  • In connection the sale, joint venture or other transfer of some or all of its company or assets, subject to the provisions of this Privacy Notice
  • To investigate or address actual or suspected fraud or other illegal activities
  • To exercise its legal rights, including enforcement of the Terms of Use for this site or another contract
  • To affiliated Pearson companies and other companies and organizations who perform work for Pearson and are obligated to protect the privacy of personal information consistent with this Privacy Notice
  • To a school, organization, company or government agency, where Pearson collects or processes the personal information in a school setting or on behalf of such organization, company or government agency.

Links


This web site contains links to other sites. Please be aware that we are not responsible for the privacy practices of such other sites. We encourage our users to be aware when they leave our site and to read the privacy statements of each and every web site that collects Personal Information. This privacy statement applies solely to information collected by this web site.

Requests and Contact


Please contact us about this Privacy Notice or if you have any requests or questions relating to the privacy of your personal information.

Changes to this Privacy Notice


We may revise this Privacy Notice through an updated posting. We will identify the effective date of the revision in the posting. Often, updates are made to provide greater clarity or to comply with changes in regulatory requirements. If the updates involve material changes to the collection, protection, use or disclosure of Personal Information, Pearson will provide notice of the change through a conspicuous notice on this site or other appropriate way. Continued use of the site after the effective date of a posted revision evidences acceptance. Please contact us if you have questions or concerns about the Privacy Notice or any objection to any revisions.

Last Update: November 17, 2020