eddorre

Found 9 posts tagged with 'security'

Buildin' the Blog: Part 5 - Refactoring: Part 2

March 14, 2009 — 1 Comment

In my last Buildin’ the Blog article, I wrote about how I cleaned up my comments controller by moving all of the processing to the model. In this follow-up article, I’m going to write about how to access properties that aren’t part of your model object (aka table).

Take for example, a simple comments database table. It might look like this:

id full_name email_address url body

As you can see this is pretty straightforward, a single comment is comprised of a full_name, email_address, and the body. These attributes can easily be checked and processed in our comment model. Here comes the tricky part.

Take for instance my comment form below:

comment form photo

Name, email address, URL, and the body of the comment can all be mapped to database table fields. Unfortunately, Remember Me and Subscribe Via Email cannot and should not.

A beginner in Rails might write something like the following in their controller code:


if params[:subscribe]
#create a subscription record here
end

This code works but it leaves a lot of logic in the controller. The controller should be fairly lightweight, “I accept input from the user pass it to the model and then I pass it back to the browser/user.”

In order to get non-database bound fields to the model we use Ruby’s attr_accessor declaration (we could use attr_writer too to only write attributes and not read them).

For example:


class Comment < ActiveRecord::Base
  attr_accessor :subscribe
end

This allows me to create a form like the following:


  <% form_for @comment do |f| %>
  <%= f.text_field :full_name %>
  ...snip...
 <%= f.check_box :subscribe %>
 <%= f.submit %>

Once this is done, I can check what the value of the checkbox was set to in the model in a callback (let’s say either a before_save or an after_save):


  def before_save
    if self.subscribe == 1
      #create a subscription record here
    end
  end

It’s that simple. Now all of my logic can be done in the model.

With that out of the way, here is something to watch out for. Let’s say that you have a comments table that looks like this:

id full_name email_address url body is_admin

Obviously, the is_admin attribute should be set by the application and not by the user but unless you protect your model, the user can set any attribute he wants. Let’s say that you have a simple comments form with full_name, email_address, url, and body. The is_admin attribute is not displayed as a form field.

A malicious user could come by and change the form by adding the following or by submitting to the comment form using cURL. Here is an example:


  <input type="checkbox" name="comment[is_admin] checked="checked" />

By crafting this form and sending it, the user automatically becomes an admin!

One way to protect your application from this type of malicious activity is by protecting fields that should never be set by the user behind the attr_protected declaration. For example:


class Comment < ActiveRecord::Base
  attr_protected :is_admin
end

This will stop malicious users from trying to set attributes that should never be set by the user.

Another Story of Lost Data

January 26, 2006 — 4 Comments

Computerworld is running yet another article on a company losing their backup tapes.

This case caught my eye immediately because it has happened in “my own backyard.” According to the article a set of disks and tapes was stolen from the car of a Providence employee while the car was at his home in Portland, Oregon.

A spokesman for Providence said that the data on the tapes was encrypted but the data on the disks was not. Walker, the spokesman, mentioned however that the data on the disks was is stored in a way that would make it difficult, if not impossible, for someone to access it, then make any sense out of it.“

This is another black eye for IT departments everywhere and a call to review their offsite tape policies.

If you are concerned that your information might be at risk, you should read the ”http://www.providence.org/oregon/hcs/newsrelease.htm">Providence press release and if necessary call their hotline number at 1-888-284-8997.

More Info on Google's VPN

September 20, 2005 — 2 Comments

I installed Google’s Secure Access VPN client and I’ve made some observations.

I’m not sure if the setup program created it or if the the client
itself created it but there is a new network connection in the Network
Connections control panel. This seems to be your standard PPTP VPN
connector.

Opening the connector is see that the username is listed as 0633492659
(seems to be a randomly generated number by the client as the second
time I connected I was assigned this number: 2466407433)
and there is no password saved. I’m assuming that the Secure Access
Client fills in the password, but that’s just an assumption.

Looking at the properties, I see that the connector is connecting to
vpn.google.com, and there are several advanced security settings
specified. According to the connector, the server requires encryption
(disconnects if the server declines) and the following options are
checked under Allow these protocols:


  • Challenge Handshake Authentication Protocol (CHAP)

  • Microsoft CHAP (MS-CHAP)

  • Microsoft CHAP Version 2 (MS-CHAP v2)

All of the other options are unchecked.

Once I opt to connect the Secure Access Client, it starts the VPN
connector and automatically connects me. The following information is
listed in the Details section of the VPN connector:


  • Authentication: MS CHAP V2

  • Encryption: MPPE 128

  • Compression: (none)

  • PPP multilink framing: Off

  • Server IP address: 192.168.230.1

  • Client IP address: 192.231.7

Doing a quick Ethereal packet capture from my laptop, it looks like the
Secure Client makes some SSL calls to vpn.google.com before connecting the VPN network connection; it probably does
this to get the username and the password to connect to the VPN.

Encrypted Wireless from Anywhere

September 20, 2005 — 0 Comments

This summer, I took a vacation to south Florida and in doing so, I
spent a significant time waiting in the airport. Most modern airports
have free wireless Internet access after the security check in points
and the airports that I’ve frequented (Portland, Phoenix, Houston, Ft.
Lauderdale) were no exception.

Most Wi-Fi networks in the airports follow a recurring motif; an open
AP (access point) that allows you to access the Internet. It’s really
convenient and easy to use but unfortunately, the problem with this is
that your communication to and from the Internet is not encrypted
whatsoever.

I don’t usually worry about this lack of encryption though. I have
access to a VPN server at work and at home so what I usually end up
doing is using the Wi-Fi at the airport then making a VPN connection to
my home network and then remote controlling and browsing, emailing, and
IM’ing from the remote controlled machine. Naturally, this is all
encrypted and I feel warm, safe, and fuzzy.

That safe feeling lasted until I couldn’t establish a VPN connection
from the Ft. Lauderdale airport. I instantly felt naked, as if my
thoughts were open to everyone and anyone. I still connected though but
I just used IM and didn’t read any of my email (corporate or home).

This got me thinking, there are probably a lot of business types out
there that use the free wireless at the airports, Starbucks, etc.
without thinking about the security of the information that they are
sending throughout the air. That thought, spawned another thought; I
envisioned a VPN service that people could use to encrypt their
wireless sessions to and from the Internet using OpenVPN. Since OpenVPN
is a TLS/SSL based VPN, it’s doubtful that someone would block the
outgoing port.

As luck (and laziness) would have it, I sat on the idea. Tonight
(morning) I opened up digg, and found this headline, “Google to offer
secure WiFi VPN.” Sound familiar? Yeah the premise is the same.
Luckily, I didn’t get into that game because Google would have crushed
me.

In order to use the service, you have to download a Windows application. Before you use it, familiarize yourself with the FAQ and the Privacy Policy.

One thing that always disturbed me about starting a service like that
was the potential to provide haxx0rs with “a free ride” to the
Internet. Think about it, now you can roll up to someone’s unsecured
wireless network in the ’burbs, start up your Google Secure Access and
start hacking away using an encrypted session.

Comcast and Telecom Providers

July 14, 2005 — 2 Comments

A friend of mine recently decided to get Comcast’s high speed Internet
access in her home. I should probably redefine what I mean by
“decided”, since it wasn’t really much of a choice. Because she is too
far from her central telephone office (CO), she can’t get any form of
reliable DSL, so she “decided” to get Comcast’s service.

Right off the bat, it was a battle with Comcast as they said that they
wouldn’t be able to provision her service without her having a computer
on site. Normally, this is not a big deal, but her only computer (a
laptop) only has a wireless network card and not a wired network card.
In order to be able to provision the modem, they wanted to charge her
to setup a wireless network instead of having me setup all that up
later.

This is all really absurd. When I moved into my new apartment a few
years ago, I called Comcast and the tech came out to provision my
modem. I had nothing in my apartment besides myself, air and some
sunlight. I did not have my computer with me at the time and he was still able to provision it.

I called Comcast in behalf of my friend and they were dead set on
having a PC with a network card ready to roll at the time of
installation. When I told them my story about not having my PC, the
support representative explained that it was a new registration
procedure and that it was necessary. Instead of fighting with Comcast,
I decided to meet the Comcast installer at her house with my laptop.

The day of the install, the technician was scheduled to show up between
2 and 4 PM. We waited and waited and he finally showed up at 4:40 PM.
The guy shows up without a cable modem (although another installer did
bring a modem 10 minutes later) and tells us that the registration
system is down so he isn’t really able to provision the modem (register the modem to communicate on their network). I was
astounded, he shows up nearly an hour late without a cable modem and to
tell us what? “No Internet for you today, folks.” To his credit, he did
call my friend on her cell phone in the morning because apparently he
had some time to do the install then. To his disservice, he failed to
leave a message then, didn’t call us to tell us that he wasn’t showing
up on time because the registration system was down, showed up without
a cable modem, and had such a blase attitude that I thought he might
slip into a coma from boredom. An example of this? At one point she
asked him about the installation charge so that she could write a
check. When asked to confirm the amount, he responded, “Something like
that.” I told her to make the check out for 25 bucks and if he said
something, just tell him, “Well, you did say something like that.”

During the long wait for the installer, my friend told me that in her
experience, this type of poor customer service is a normal thing with
Comcast. I’ve heard others say the same thing about DSL, and telecom
providers (Qwest comes to mind). Are we so conditioned to poor service
from these types of companies that we think that this is normal?

I hate it when the little guy gets trampled by the “Big Corporation”.
Companies should step up to the plate and admit when things go wrong
and offer to make amends with their customers. I love to fight with
companies to see if they step up and do something, so after the
installer left, I called Comcast and complained about everything. I
managed to get her installation fee waived (as it should have been).

There were other problems with Comcast, but I’ll let my other post (soon to be written explain what those are).

Network Security

April 03, 2005 — 0 Comments

Not too long ago my company was seeking an industry specific security certification. Some of it covered physical security but a lot of it covered infosec. Information Security is not a goal, it’s a process. During the process of certification, I ran across the book Inside Network Perimeter Security (Second Edition) by Stephen Northcutt (and other authors).

This book rocks. I wish I had this book before we started this process, I think it would have made it a lot easier. If you work with information security in any way you owe it to yourself to get this book and read it. Packet filtering, stateful firewalls, proxies, VPN, policies, IDS/IPS, it’s all in here.

Wi-Fi Home Camera Security System

October 15, 2004 — 0 Comments

When I own a home, I’m going install cameras inside and out so that I can see what’s going on when I’m not there. Call me paranoid or whatever, but after you’ve worked for a security company you know that audible alarms aren’t enough. With the advent of wireless cameras, I’ve been thinking about what it would take to setup a home camera security system. That’s where this article comes in. Apparently this guy (Joe Barr) installed a Home Camera Security System for his neighbor using wireless enabled cameras from D-Link and some open source software called ZoneMinder. It’s definitely a good read for those security buffs out there.

Now I’m just trying to find ouy why the author went through all the trouble to install this system and put in a steel reinforced door for his neighbor Susan. I guess he subscribes to the “love thy neighbor” theory.

How to Give a User(s) Permission to Change the Owner of a DTS Package

October 04, 2004 — 2 Comments

UPDATE: Apparently if SQL Server considers you to be dbo on the msdb database the IF (ISNULL, 0) <> 1) function will return false. It was happening to my users, so instead of using the role that I created (db_ChangeDTSOwner) I used the domain group that the user was in using this notation: “domaindomain_group”.

So the code below would read “IF (ISNULL, 0) <> 1)”. If you do not have a domain, then I would make sure that the user(s) are not part of the dbo group and they remain part of the db_ChangeDTSOwner role in the msdb database.

The simple way to do this in SQL Server 2000 is to add the user or group to the System Administrators Server Role but that breaks one of the major security tenets out there; only give a user the tools to do their job and nothing more. So I had to find another alternative. Here is what I came up with:

  1. Create a role in the msdb database called db_ChangeDTSOwner and add the users or groups that you want to this role.
Create the following stored procedures:

CREATE PROCEDURE sp_new_reassign_dtspackageowner
  name sysname,<br />&nbsp; @id UNIQUEIDENTIFIER,<br />&nbsp; @newloginname sysname<br />AS<br />&nbsp; SET NOCOUNT ON<br />&nbsp; --// First, is this a valid login?<br />&nbsp; IF SUSER_SID(newloginname) IS NULL
  BEGIN
    RAISERROR
    RETURN - Failure
  END
  -
// Does the specified package (uniquely) exist?  Referencing by name only may not be unique.
  -// We do a bit of a hack here as SQL can’t handle a DISTINCT clause with UNIQUEIDENTIFIER.
  -
// id will get the first id returned; if only name specified, see if there are more.<br />&nbsp; DECLARE @findid UNIQUEIDENTIFIER<br />&nbsp; SELECT @findid = id FROM sysdtspackages<br />&nbsp;&nbsp;&nbsp; WHERE (name IS NOT NULL OR id IS NOT NULL)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AND (name IS NULL OR name = name)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AND (id IS NULL OR id = id)<br />&nbsp; IF @rowcount = 0
  BEGIN
    DECLARE pkgnotfound NVARCHAR(200)<br />&nbsp;&nbsp;&nbsp; DECLARE @dts_package_res NVARCHAR(100)<br />&nbsp;&nbsp;&nbsp; SELECT @pkgnotfound = FORMATMESSAGE(14599) + ' = ''' + ISNULL(name, FORMATMESSAGE) + ‘’’; ’ + FORMATMESSAGE + ’ {’
    SELECT pkgnotfound = @pkgnotfound + CASE WHEN @id IS NULL THEN FORMATMESSAGE(14589) ELSE CONVERT(NVARCHAR(50), @id) END + '}.{'<br />&nbsp;&nbsp;&nbsp; SELECT @pkgnotfound = @pkgnotfound + FORMATMESSAGE(14589) + '}'<br />&nbsp;&nbsp;&nbsp; SELECT @dts_package_res = FORMATMESSAGE(14594)<br />&nbsp;&nbsp;&nbsp; RAISERROR(14262, 16, 1, @dts_package_res, @pkgnotfound)<br />&nbsp;&nbsp;&nbsp; RETURN(1) -- Failure<br />&nbsp; END ELSE IF @name IS NOT NULL AND @id IS NULL AND<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EXISTS (SELECT * FROM sysdtspackages WHERE name = @name AND id &lt;&gt; @findid)<br />&nbsp; BEGIN<br />&nbsp;&nbsp;&nbsp; RAISERROR(14595, -1, -1, @name)<br />&nbsp;&nbsp;&nbsp; RETURN(1) -- Failure<br />&nbsp; END<br />&nbsp; SELECT @id = @findid<br />&nbsp; --// Only the owner of DTS Package ''%s'' or a member of the sysadmin role may reassign its ownership.<br />&nbsp; --// sp_add_dtspackage ensures that all versions have the same owner_sid.<br />&nbsp; IF (ISNULL(IS_MEMBER(N'db_ChangeDTSOwner'), 0) &lt;&gt; 1)<br />&nbsp; BEGIN<br />&nbsp;&nbsp;&nbsp; IF (NOT EXISTS (SELECT * FROM sysdtspackages WHERE id = @id AND owner_sid = SUSER_SID()))<br />&nbsp;&nbsp;&nbsp; BEGIN<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SELECT @name = name FROM sysdtspackages WHERE id = @id<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RAISERROR (14585, -1, -1, @name)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RETURN(1) -- Failure<br />&nbsp;&nbsp;&nbsp; END<br />&nbsp; END<br />&nbsp; --// Everything checks out, so reassign the owner.<br />&nbsp; --// Note that @newloginname may be a sql server login rather than a network user,<br />&nbsp; --// which is not quite the same as when a package is created.<br />&nbsp; UPDATE sysdtspackages<br />&nbsp;&nbsp;&nbsp; SET owner_sid = SUSER_SID(newloginname),
                owner = newloginname<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WHERE id = @id<br />&nbsp; RETURN 0&nbsp;&nbsp;&nbsp; -- SUCCESS</div><br />The above code is an altered Microsoft stored procedure. Instead of checking to see if the user is in the System Administrators Server Role is checks to see if the user or group is in the db_ChangeDTSOwner role. <br /><br /> <div class="codeSample">CREATE&nbsp; PROCEDURE proc_DTSChangeOwner<br />package_name sysname,
old_owner sysname,<br />new_owner sysname
AS
DECLARE id uniqueidentifier, @name sysname, @error INT<br />/**<br />Author: Carlos Rodriguez<br />Date Created: 1-13-2004<br />Summary: Changes owner of DTS package so that edits can be made to it<br />ChangeLog:<br />----------------------------------------------------------------------<br />Date: 1-14-2003 <br />Author: Carlos Rodriguez<br />Change: Added logging to a table<br />----------------------------------------------------------------------<br /><br />**/<br /><br />/**<br /><br />If the package name or the old owner don't match up, display error message and stop procedure<br /><br />**/<br />IF (NOT EXISTS (SELECT * FROM msdb..sysdtspackages WHERE [owner] = @old_owner AND [name] = @package_name))<br />BEGIN<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RAISERROR('Package ''%s'' does not exist or owner name is wrong', 16, 1, @package_name)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RETURN<br />END<br /><br />--First, is this a valid login?<br />&nbsp; IF SUSER_SID(new_owner) IS NULL
  BEGIN
    RAISERROR
    RETURN - Failure
  END
SET name = @package_name<br />/**<br />For each instance of a package name in the msdb..sysdtspackages table with the old owner name, let's <br />change that to the new owner name. In the msdb..sysdtspackages table, there can be multiple versions<br />of the same package so we need to do this.<br />**/<br />DECLARE cur_sysdtspackages CURSOR FOR <br />&nbsp;&nbsp; SELECT DISTINCT [name], [id]<br />&nbsp;&nbsp; FROM sysdtspackages <br />&nbsp;&nbsp; WHERE [owner] = @old_owner AND [name] = @package_name<br />&nbsp;OPEN cur_sysdtspackages<br />&nbsp;FETCH NEXT FROM cur_sysdtspackages<br />&nbsp;INTO @name, @id<br />&nbsp;WHILE @FETCH_STATUS = 0
 BEGIN
-Call undocumented stored procedure to change the owner of the package
     EXEC sp_new_reassign_dtspackageowner name=name, id=id, newloginname=new_owner
     FETCH NEXT FROM cur_sysdtspackages
     INTO name, @id<br />&nbsp;END<br />&nbsp;CLOSE cur_sysdtspackages<br />&nbsp;DEALLOCATE cur_sysdtspackages<br />--Add a record to the log (DTSChangeOwnerLog table)<br />INSERT INTO DTSChangeOwnerLog<br />VALUES(name, @old_owner, @new_owner, getdate())
GO

And finally create this table for logging:

CREATE TABLE [DTSChangeOwnerLog] (
            [record_id] [int] IDENTITY (1, 1) NOT NULL ,
            [package_name] [varchar] (100) NULL ,
            [old_owner] [varchar] (30) NULL ,
            [new_owner] [varchar] (30) NULL ,
            [dt] [datetime] NULL ,
             PRIMARY KEY  NONCLUSTERED
            (
                        [record_id]
            )  ON [PRIMARY]
) ON [PRIMARY]
GO

Remember to give the user or group execute permissions on the new stored procedures. A user can change the owner DTS package by running this code from the msdb database:

EXEC proc_DTSChangeOwner ‘name of DTS package’, ‘domainolduser’, ‘domain
ewuser’.

Security

January 23, 2004 — 1 Comment

Security, especially computer and network security, is something that most people don’t understand very well. In fact, I find that there are 2 camps of people when it comes to computer security. The first camp knows that security is necessary but in the overall scheme of things, it is just a hindrance. Something that network administrators/system administrators use to make their lives harder. I have found out that this group is the same one that yells the loudest once security is compromised or fails in some way. The other camp knows that security is necessary and works with the changes offering constructive criticsm where it is needed.


Security, much like other things, is a process not a goal. It’s not something that can be “achieved” and then never looked at again. It is something that continually needs time and attention. Hopefully, people will come to understand that computer security/network security is just as necessary as the locks on your doors and windows.