The free market is the most inclusive socio-economic system yet developed.
The secret to making the free market work is for people to see themselves as owners, and not just workers.
Sadly, the political left and right have been working on a paradigm where there is a professional centralized class of owners ... with everyone else reduced to wage labor.
This model is absurd in a day when machines are systematically reducing the value of wage labor.
The two most important things that people own are their minds and their bodies.
Both socialized medicine and insurance are a direct assault on the notion that people own their bodies. In both systems, your physical body is not your property. Your body is part of a pool.
The Medical Savings and Loan is a structured savings program that is a bit like insurance in that it provides funds for emergency care; however it shifts the paradigm from group funded care to self funded care.
The Medical Savings and Loan has the same amount of money currently spent on insurance. However, the structure re-establishes the idea that people own their own body and are the primary agent charged with the care of they body they own.
The program uses a system of health care advocates to challenge healthy people with the need to save and engage in preventative medicine. The advocates then help people manage resources when they need care.
By teaching people to treat their body as thing that they own helps re-establish the concepts at the heart of the free market system that our founders established.
Tweet Button: Tweet
Monday, February 21, 2011
Thursday, February 17, 2011
Progressive Dialectics
The Iranians praised the Egyptian antigovernment protests and are even actively stoking the revolution in Bahrain, while suppressing similar protests in their own nation.
Some members of the mainstream media have caught on to the duplicity.
This duplicity of having a different set of rules for the left and right is the beating heart of the modern progressive dialectic.
This idea is that the intelligentsia can engineer society by progressing society through a number of irreversible steps. If the army can take two steps forward with an occasional step back, the army will eventually conquer.
Groups using this modern dialectic try to structure one way valves. A group might have an aggressive recruitment program, then ostracize anyone who leaves the group.
Unions structure an election process where it is easy to vote a union in, and next to impossible to vote it out again.
These mechanisms are inherently dishonest.
Unfortunately, people are often only able to see the duplicity when exercised by the opposition.
Even worse, often leaders, watching the dishonest techniques of their opposition, respond by doubling down and becoming more dishonest in discourse themselves.
The challenge for the lovers of freedom is to challenge the inherent duplicity of the current political discourse, and turn our society back on the path of liberty and prosperity by genuine, honest debate about the nature of freedom.
Some members of the mainstream media have caught on to the duplicity.
This duplicity of having a different set of rules for the left and right is the beating heart of the modern progressive dialectic.
This idea is that the intelligentsia can engineer society by progressing society through a number of irreversible steps. If the army can take two steps forward with an occasional step back, the army will eventually conquer.
Groups using this modern dialectic try to structure one way valves. A group might have an aggressive recruitment program, then ostracize anyone who leaves the group.
Unions structure an election process where it is easy to vote a union in, and next to impossible to vote it out again.
These mechanisms are inherently dishonest.
Unfortunately, people are often only able to see the duplicity when exercised by the opposition.
Even worse, often leaders, watching the dishonest techniques of their opposition, respond by doubling down and becoming more dishonest in discourse themselves.
The challenge for the lovers of freedom is to challenge the inherent duplicity of the current political discourse, and turn our society back on the path of liberty and prosperity by genuine, honest debate about the nature of freedom.
Tuesday, February 15, 2011
The Two Fronts of the Regulatory War
Progressives have been busy in both the business world and government creating a large number of businesses that are dependent on government regulation and government largess.
Many Libertarians seem to ride on the hope that they can restore the free market simply by cutting the regulations and supplements.
Unfortunately, cutting the chords of dependency between government and business is likely to result in economic chaos and result in a demand for greater government involvement in business.
The economic collapse of 2008 showed that one cannot simply deregulate a market jacked up on regulatory devices like Freddie Mac, Fannie Mae, government backed mortgage securities, etc..
To actually succeed in restoring the free market, Libertarians need to approach the issue in the same multi-prong approach of the progressives.
Progressives created business models that were dependent on government regulation and funds.
Libertarians need counter this attack by developing business models that accomplish the stated goals of the progressives. With these business models in place, libertarian politicians can move in to rid the market of the corruption caused by previous generations of progressive duplicity.
Ahem, dare I mention that the Medical Savings and Loan just happens to be a free market version of health care reform that accomplishes just such a feat.
Many Libertarians seem to ride on the hope that they can restore the free market simply by cutting the regulations and supplements.
Unfortunately, cutting the chords of dependency between government and business is likely to result in economic chaos and result in a demand for greater government involvement in business.
The economic collapse of 2008 showed that one cannot simply deregulate a market jacked up on regulatory devices like Freddie Mac, Fannie Mae, government backed mortgage securities, etc..
To actually succeed in restoring the free market, Libertarians need to approach the issue in the same multi-prong approach of the progressives.
Progressives created business models that were dependent on government regulation and funds.
Libertarians need counter this attack by developing business models that accomplish the stated goals of the progressives. With these business models in place, libertarian politicians can move in to rid the market of the corruption caused by previous generations of progressive duplicity.
Ahem, dare I mention that the Medical Savings and Loan just happens to be a free market version of health care reform that accomplishes just such a feat.
Monday, February 14, 2011
Product Liability in Health Care
Imagine that there was a standard medical procedure that cost $100 to deliver. One out of every one hundred procedures resulted in a complication that cost $10,000. That's a 1% fail rate.
The expected costs of 100 procedures is $10,000 for the procedure. The cost of the complication is $10,000.
In this simple example, the product liability is one half of the total cost of the procedure.
As this liability is related to the product, it makes sense for the cost of the liability to be included in the product. IMHO, the procedure should cost $200 with $100 per procedure set aside to cover the rare complication.
The advantage of the product liability model is that it encourages the medical system to find ways to reduce the costs associated with complications on a procedure by procedure basis. One can reduce the cost either by finding ways to reduce the risks of complication or by finding ways to lower the cost of treatment of the complication.
The model also allows the medical professional to sell the procedure and risk at a fair and reasonable price.
We can see the role that procedural risk comes to play in birth. Birth is risky business. Lets say that a standard pregnancy and birth costs $3000, but complications during a birth can quickly skyrocket the costs into the stratosphere.
A pregnancy center would be wise to present the entire birth as a product with a single predictable price that includes the liability. The center would charge a figure that includes the standard deliver plus any intensive care resulting from complications.
Insurance formed around an individual procedure (like birth) allows the care provider to create a better product.
People reading this blog might think that I hate insurance. In truth, what I want is a system designed so that insurance provides the maximum value which happens with product liability.
Our current system is dysfunctional. Health Insurance companies sell risk. They prefer the model where the complications associated with a procedure are handled separately from the procedure, making it scary for people to go without insurance.
The medical savings and loan is not adverse to actuarial analysis or to insurance. The program encourages risk analysis to help people handle the risks associated with life.
In the paradigm where people self fund their care, the insurance and risk analysis will be targetted to individual procedures, products and activities allowing for a much more dynamic health care system that empowers both the patient and medical provider.
The expected costs of 100 procedures is $10,000 for the procedure. The cost of the complication is $10,000.
In this simple example, the product liability is one half of the total cost of the procedure.
As this liability is related to the product, it makes sense for the cost of the liability to be included in the product. IMHO, the procedure should cost $200 with $100 per procedure set aside to cover the rare complication.
The advantage of the product liability model is that it encourages the medical system to find ways to reduce the costs associated with complications on a procedure by procedure basis. One can reduce the cost either by finding ways to reduce the risks of complication or by finding ways to lower the cost of treatment of the complication.
The model also allows the medical professional to sell the procedure and risk at a fair and reasonable price.
We can see the role that procedural risk comes to play in birth. Birth is risky business. Lets say that a standard pregnancy and birth costs $3000, but complications during a birth can quickly skyrocket the costs into the stratosphere.
A pregnancy center would be wise to present the entire birth as a product with a single predictable price that includes the liability. The center would charge a figure that includes the standard deliver plus any intensive care resulting from complications.
Insurance formed around an individual procedure (like birth) allows the care provider to create a better product.
People reading this blog might think that I hate insurance. In truth, what I want is a system designed so that insurance provides the maximum value which happens with product liability.
Our current system is dysfunctional. Health Insurance companies sell risk. They prefer the model where the complications associated with a procedure are handled separately from the procedure, making it scary for people to go without insurance.
The medical savings and loan is not adverse to actuarial analysis or to insurance. The program encourages risk analysis to help people handle the risks associated with life.
In the paradigm where people self fund their care, the insurance and risk analysis will be targetted to individual procedures, products and activities allowing for a much more dynamic health care system that empowers both the patient and medical provider.
Friday, February 11, 2011
Freedom and Social Justice
Not all revolutions turn out well. For that matter, most revolutions seem to go sour.
As we watch revolution on the news, it is worthwhile to discuss the differences between those that turn out well and those that turn out poorly.
Revolutions based on a desire for freedom tend to have a better track record than those predicated on a demand for social justice.
This is not simply because "social justice" is often used as a code word for "Marxism."
The difference can be described by distinguishing the goals of a society from its foundation.
I believe that social justice is a good thing. But social justice is a goal. It is an ideal to which we aspire.
The actual concept of social justice is nebulous. Different people have different concepts of social justice often based on their individual perspectives.
Revolutions that attempt to found a society on social justice tend to fail because such revolutions confuse goals with the foundation of society. A revolution might launch with a demand to struggle against a group that people see as the source of social injustice. A society that builds administering social justice against an enemy becomes a source of social injustice.
The classical liberals that founded the United States of America stumbled upon the realization the freedom serves as a strong foundation for a society.
In a free society that respects property rights, people are able to develop their own ideals and are then able to use their property to pursue their ideals.
A free society in which people hold the ideal of social justice in high esteem is more likely to achieve real lasting social justice than one that tries to build social justice into the foundation of society.
Such a free society allows people to not only discuss and define their ideals by openly invites people to use their property in achieving their ideals.
When I hear a revolutionary or progressive demanding that we fundamentally change society to impose social justice on their enemies, I fear. However, when I hear people talk about freedom and the pursuit of their ideals, then I feel hope for such people are the ones most likely to bring about a truly just and prosperous society.
As we watch revolution on the news, it is worthwhile to discuss the differences between those that turn out well and those that turn out poorly.
Revolutions based on a desire for freedom tend to have a better track record than those predicated on a demand for social justice.
This is not simply because "social justice" is often used as a code word for "Marxism."
The difference can be described by distinguishing the goals of a society from its foundation.
I believe that social justice is a good thing. But social justice is a goal. It is an ideal to which we aspire.
The actual concept of social justice is nebulous. Different people have different concepts of social justice often based on their individual perspectives.
Revolutions that attempt to found a society on social justice tend to fail because such revolutions confuse goals with the foundation of society. A revolution might launch with a demand to struggle against a group that people see as the source of social injustice. A society that builds administering social justice against an enemy becomes a source of social injustice.
The classical liberals that founded the United States of America stumbled upon the realization the freedom serves as a strong foundation for a society.
In a free society that respects property rights, people are able to develop their own ideals and are then able to use their property to pursue their ideals.
A free society in which people hold the ideal of social justice in high esteem is more likely to achieve real lasting social justice than one that tries to build social justice into the foundation of society.
Such a free society allows people to not only discuss and define their ideals by openly invites people to use their property in achieving their ideals.
When I hear a revolutionary or progressive demanding that we fundamentally change society to impose social justice on their enemies, I fear. However, when I hear people talk about freedom and the pursuit of their ideals, then I feel hope for such people are the ones most likely to bring about a truly just and prosperous society.
Thursday, February 10, 2011
NO_AUTO_VALUE_ON_ZERO
The annoying thing about MYSQL is that, by default, it's autoincrement program triggers on zero. IMHO, it should only trigger on Null.
If the column Id is set to AUTO_INCREMENT in Table Data_Table the command:
will insert a row (#, 'zero') where # is the next number in the auto insert sequence.
Because the MySQL auto increment triggers on 0, copying a table from one computer to another changes the zero row.
In my import to the new database, the system changed some of my zero rows and caused me some headaches.
Of course, these headache were nothing like the one I get when talking to Set Theorists.
On more than one occasion I've been shouted down by Set Theory Nazis dedicated to the cause of including zero in the definition of the set of Natural Numbers. Set Theorists want to include zero in sets so that they become a group. I primary school, they defined the Natural numbers as {1, 2, 3, ...} and Whole Numbers as {0, 1, 2, 3, ...}
[the horror]
Set Theorists want the Natural numbers defined as {0, 1, 2, 3, ...} and anyone who begins counting at 1 is an idiot.
As Relational Database Theory came directly from Set Theory, it is astounding that an RBDMS system like MySQL would make defining a zero record so difficult.
The behavior of MySQL is even more astounding since this RDBMS is usually paired with languages like C, PHP or Java that use offsets (not counters) for arrays. The first position in such arrays is 0, not 1. In Java the first element in myArray is myArray[0]. In Basic, myArray[1] is the first element.
As mentioned, I've been shouted down by Set Theory Nazis who ridicule neophytes who start sets with 1. So it is amusing to read MySQL forum posts with people equally convinced that SQL Tables should exclude a zero row.
Personally, I think it best to realize that sets beginning with 1 or 0 are valid logical constructs with different properties. IMHO, a RDBMS should facilitate both programming styles. As such NO_AUTO_VALUE_ON_ZERO should be the default.
If the column Id is set to AUTO_INCREMENT in Table Data_Table the command:
INSERT INTO Data_Table (id, firstcolumn) VALUES (0,'zero');
will insert a row (#, 'zero') where # is the next number in the auto insert sequence.
Because the MySQL auto increment triggers on 0, copying a table from one computer to another changes the zero row.
In my import to the new database, the system changed some of my zero rows and caused me some headaches.
Of course, these headache were nothing like the one I get when talking to Set Theorists.
On more than one occasion I've been shouted down by Set Theory Nazis dedicated to the cause of including zero in the definition of the set of Natural Numbers. Set Theorists want to include zero in sets so that they become a group. I primary school, they defined the Natural numbers as {1, 2, 3, ...} and Whole Numbers as {0, 1, 2, 3, ...}
[the horror]
Set Theorists want the Natural numbers defined as {0, 1, 2, 3, ...} and anyone who begins counting at 1 is an idiot.
As Relational Database Theory came directly from Set Theory, it is astounding that an RBDMS system like MySQL would make defining a zero record so difficult.
The behavior of MySQL is even more astounding since this RDBMS is usually paired with languages like C, PHP or Java that use offsets (not counters) for arrays. The first position in such arrays is 0, not 1. In Java the first element in myArray is myArray[0]. In Basic, myArray[1] is the first element.
As mentioned, I've been shouted down by Set Theory Nazis who ridicule neophytes who start sets with 1. So it is amusing to read MySQL forum posts with people equally convinced that SQL Tables should exclude a zero row.
Personally, I think it best to realize that sets beginning with 1 or 0 are valid logical constructs with different properties. IMHO, a RDBMS should facilitate both programming styles. As such NO_AUTO_VALUE_ON_ZERO should be the default.
Wednesday, February 09, 2011
Changes to Program
I made two big changes to my email address encryption program.
The first is that I split the password in half. The first half of the password is in the PHP file and second half in the MySQL program. I also added an addNew directive. That way I could search for email addresses without creating a new address:
The line that does the encryption is now:
So I call the function with "SELECT getEmailId('bob@example.com','pass')". The villain would have to hack both my PHP program and my SQL Database to figure out that the pass word is "password"!
If I wanted even better security. I could double encrypt the password. Splitting the security token between the PHP code and a MYSQL procedure adds a layer of obfuscation.
BTW, I could have chosen to double encrypt the password, but Concat is faster.
The first is that I split the password in half. The first half of the password is in the PHP file and second half in the MySQL program. I also added an addNew directive. That way I could search for email addresses without creating a new address:
CREATE FUNCTION getEmailId(str VARCHAR(255), ipwd CHAR(4), addNew CHAR(1))
The line that does the encryption is now:
SET encrypted = AES_Encrypt(Lower(str),Concat(ipwd,'word'));
So I call the function with "SELECT getEmailId('bob@example.com','pass')". The villain would have to hack both my PHP program and my SQL Database to figure out that the pass word is "password"!
If I wanted even better security. I could double encrypt the password. Splitting the security token between the PHP code and a MYSQL procedure adds a layer of obfuscation.
BTW, I could have chosen to double encrypt the password, but Concat is faster.
Tuesday, February 08, 2011
My First MySQL Function
My fancy new cloud server uses MySQL 5.0.91 which includes support for stored functions and procedures. I realize this release is old hat to the annointed, but it's new to me.
Anyway, I spent most of today writing my very first MySQL STORED FUNCTION.
While writing the function, I realized that I had become addicted to a debugger. Apparently, the MySQL doesn't say what is wrong with a program. It simply fails if something is wrong with the syntax.
Finally, I decided to write the program running each line of code through the SQL Query window until I had a procedure that worked.
Anyway, the goal of my first STORED FUNCTION is to encrypt and decrypt the email addresses from the Registration form. The registration form encrypted the email addresses, but I never wrote a decrypt program.
Anyway, since I will release some new features, I decided I should create a password reset program. So, I decided it would be helpful to be able to decrypt the email addresses.
In this new program, I will store the encrypted email addresses in the table Email_X. It has the definition. email_id is a primary key with AUTO_INCREMENT
The getEmailId() takes an email address. Converts it to lower case and runs AES_Encrypt with the unimaginative password "password". I convert to make searching for an email address easier. "Bob@example.com" encrypts differently than "bob@example.com" & and I want to find all occurences of Bob's email address.
I will store the email_id in the user table. This makes it easy to find all the accounts owned by the same email address because they will have the name number.
I could find all the accounts for bob@example.com with the SQL Query:
I can now call this function with an email address. It will look to see if the address is in Email_X. If so, it returns its current id. If not it will create a new entry in Email_X with an encrypted string in the place of the email addresss.
To decrypt the email addresses, I created the following program:
getEmailAddr() takes a number then decrypts the encrypted binary string. The function updates a counter every time someone accesses an address. I also added the block_yn feature. If a person requests their email address removed from the system, I can block it at the encryption level.
The next step in this program is to create a send mail program.
The send mail program will decrypt the email address and record the transaction. The number of decrypts should equal the number of emails sent. If it does not, then I know I have a hacker going at the database.
Anyway, I spent most of today writing my very first MySQL STORED FUNCTION.
While writing the function, I realized that I had become addicted to a debugger. Apparently, the MySQL doesn't say what is wrong with a program. It simply fails if something is wrong with the syntax.
Finally, I decided to write the program running each line of code through the SQL Query window until I had a procedure that worked.
Anyway, the goal of my first STORED FUNCTION is to encrypt and decrypt the email addresses from the Registration form. The registration form encrypted the email addresses, but I never wrote a decrypt program.
Anyway, since I will release some new features, I decided I should create a password reset program. So, I decided it would be helpful to be able to decrypt the email addresses.
In this new program, I will store the encrypted email addresses in the table Email_X. It has the definition. email_id is a primary key with AUTO_INCREMENT
CREATE TABLE IF NOT EXISTS Email_X (
email_id int(10) unsigned NOT NULL auto_increment,
email_bin varbinary(255) NOT NULL,
decrypt_cnt int(11) NOT NULL default '0',
block_yn char(1) NOT NULL default 'N',
PRIMARY KEY (email_id)
) AUTO_INCREMENT=1 ;
The getEmailId() takes an email address. Converts it to lower case and runs AES_Encrypt with the unimaginative password "password". I convert to make searching for an email address easier. "Bob@example.com" encrypts differently than "bob@example.com" & and I want to find all occurences of Bob's email address.
I will store the email_id in the user table. This makes it easy to find all the accounts owned by the same email address because they will have the name number.
I could find all the accounts for bob@example.com with the SQL Query:
SELECT * FROM User_Table WHERE email_id = getEmailId('bob@example.com');
DROP FUNCTION IF EXISTS getEmailId;
DELIMITER $$
CREATE FUNCTION getEmailId(str VARCHAR(255))
RETURNS INT
BEGIN
DECLARE rv INT DEFAULT 0;
DECLARE encrypted VARBINARY(255) DEFAULT NULL;
IF (str = '') THEN
SET rv = 0;
ELSE
SET encrypted = AES_Encrypt(Lower(str),'password');
SELECT email_id INTO rv FROM Email_X WHERE email_bin = encrypted;
IF !(rv > 0) THEN
INSERT INTO Email_X (email_bin) VALUES (encrypted);
SET rv = LAST_INSERT_ID();
END IF;
END IF;
RETURN rv;
END$$
DELIMITER ;
I can now call this function with an email address. It will look to see if the address is in Email_X. If so, it returns its current id. If not it will create a new entry in Email_X with an encrypted string in the place of the email addresss.
To decrypt the email addresses, I created the following program:
DROP FUNCTION IF EXISTS getEmailAddr;
DELIMITER $$
CREATE FUNCTION getEmailAddr(eid INT)
RETURNS VARCHAR(255)
BEGIN
DECLARE rv VARCHAR(255) DEFAULT NULL;
DECLARE blockMe CHAR(1) DEFAULT 'N';
IF eid > 0 THEN
SELECT AES_Decrypt(email_bin, 'password'), block_yn INTO rv, blockMe FROM Email_X
WHERE email_id = eid;
IF blockMe = 'N' THEN
UPDATE Email_X SET decrypt_cnt = decrypt_cnt + 1
WHERE email_id = eid;
ELSE
SET rv = '';
END IF;
END IF;
RETURN rv;
END$$
DELIMITER ;
getEmailAddr() takes a number then decrypts the encrypted binary string. The function updates a counter every time someone accesses an address. I also added the block_yn feature. If a person requests their email address removed from the system, I can block it at the encryption level.
The next step in this program is to create a send mail program.
The send mail program will decrypt the email address and record the transaction. The number of decrypts should equal the number of emails sent. If it does not, then I know I have a hacker going at the database.
Setting Up the Server
I've spent the last week (from 1/31 to today) setting up a new webhosting account for the community color sites.
A word to the wise. If you are setting up a new hosting account, and it does not work perfectly ... it is best just to just cut losses and run.
My new hosting account was assigned a dedicated IP address that was in use by another server. The set up got half way through the install, then crashed.
I called tech support who tried to rebuild the account by hand, but there were problems. One problem occurred with the DNS entry. The install tried to map my domain name to a IP assigned to another server, and created an incorrect DNS entry in the web hosts DNS system.
The DNS change could not propagate because the webhost's DNS server kept rejecting the DNS propagation.
Calls to tech support were tainted with the assumption that I was clueless in regards to DNS changes.
Finally, I found the PHP function dns_get_record() which shows the DNS from the perspective of a web server. You can put this on any PHP site and see your DNS record (change 'example.com' to your domain).
With this data in hand, I was able to convince tech support to consider the possibility that the DNS problem was on their end and not with my DNS provider. Sure enough, as soon as they corrected the record on their DNS server, the change propagated through out the DNS world at the next TTL.
I had a second technical support call about broken security features in my account. There is probably a big star next to my name saying "This guy is a real jerk."
Tech support no longer gives stars to people who perservere through problems caused by a technical glitch in a product.
I had given myself seven days to move the accounts. I spent five on a DNS problem caused by the host and two on calls about broken services in the account.
That gave me a negative amount of time to work on the site transfer itself.
So, I did a blind transfer of data between the servers.
There was a conflict in transferring the Change Request and User Session tables. There are many broken pages and links.
At least, I am on a new server and have resources to add new functionality.
A word to the wise. If you are setting up a new hosting account, and it does not work perfectly ... it is best just to just cut losses and run.
My new hosting account was assigned a dedicated IP address that was in use by another server. The set up got half way through the install, then crashed.
I called tech support who tried to rebuild the account by hand, but there were problems. One problem occurred with the DNS entry. The install tried to map my domain name to a IP assigned to another server, and created an incorrect DNS entry in the web hosts DNS system.
The DNS change could not propagate because the webhost's DNS server kept rejecting the DNS propagation.
Calls to tech support were tainted with the assumption that I was clueless in regards to DNS changes.
Finally, I found the PHP function dns_get_record() which shows the DNS from the perspective of a web server. You can put this on any PHP site and see your DNS record (change 'example.com' to your domain).
<?php echo '<pre>'; print_r(dns_get_record('example.com'); echo '</pre>'; ?>
With this data in hand, I was able to convince tech support to consider the possibility that the DNS problem was on their end and not with my DNS provider. Sure enough, as soon as they corrected the record on their DNS server, the change propagated through out the DNS world at the next TTL.
I had a second technical support call about broken security features in my account. There is probably a big star next to my name saying "This guy is a real jerk."
Tech support no longer gives stars to people who perservere through problems caused by a technical glitch in a product.
I had given myself seven days to move the accounts. I spent five on a DNS problem caused by the host and two on calls about broken services in the account.
That gave me a negative amount of time to work on the site transfer itself.
So, I did a blind transfer of data between the servers.
There was a conflict in transferring the Change Request and User Session tables. There are many broken pages and links.
At least, I am on a new server and have resources to add new functionality.
Sunday, February 06, 2011
Magic Quotes and Lesson in Security
PHP is a kludgy language. It is common for a PHP page to take raw data from web input. Translate the data into an SQL string and execute a SQL query. A programmer might have a page with URL "page.php?id=5." The program page.php might have the code:
mysql_query('SELECT * FROM PageData WHERE id = '.$id);
$id contains the variable in the URL string. If the id is 5, PHP sends the SQL command "SELECT * FROM PageData WHERE id = 5" to the database. Since one is sending straight text to mysql, hackers have learned that they can often inject SQL code into PHP strings. For example one might call the page.php with the command ("page.php?id=5; 'SELECT password FROM SecurityTable WHERE user=1').
The variable $id now contains the string "5; 'SELECT password FROM SecurityTable WHERE user=1'". The command in mysql_query() is now sending two SQL commands to the database engine.
When looking at logs for a web site; you will occasionally find hackers sending commands to pages to inject SQL strings into PHP pages. Hackers will even run scripts that systematically attack every variable sent to a page to see if it was properly validates. This type of attack is called an injection script.
The key to this sql injection script is the single quote character "'" which breaks out of one sql command and starts another.
To prevent injection scripts, programmers must validate all input from the web. Validating a string involves changing the quote character into something that won't be wrongly interpretted by SQL. PHP created a program called addslashes(). addslashes() escapes quotes with a slash. addslashes() translates "'" into "\'" which the database correctly interprets as a quote and not a break in a SQL statement.
Early PHP manuals instructed programmers to run addslashes() on all code from the web.
But even one sloppy piece of code in a large program created a security hole.
Tired of being hacked Webhosts came up with the clever idea called "Magic Quotes"
Magic quotes automatically runs addslashes() on all data coming into the web site. There were two big mistakes in this decision.
The first was that addslashes() escapes slashes. If you add slashes on the same data twice, you start getting extra slashes. the command addslashes("'") returns "\'". addslashes(addslashes("'")) returns "\\\'". Running the program recursively three times returns "\\\\\\\'"
This is actually an interesting application of the reflective paradox.
All of the code written to PHP best practices prior to MagicQuotes started returning multiple slashes. Programmers had to convert their code to addslashes(stripslashes(data)).
The second major flaw of Magic Quotes is that people around the world want to write programs in their native language using their native character sets.
Different character sets around the world use different delimiters for text. addslashes() and Magic Quotes assumes everything was written in a latin based character set. Different character sets use different delimiters.
One does not know what characters need to be escaped until after establishing the connection to the database. Each database has its own preferred mechanism for validating data. MySQL offers an awkward function called mysql_real_escape_string().
Magic Quotes turned out be a fiasco. Programmers who've written their own validation procedures want the feature off. A small number of programs have grown dependent on it.
Now here is the interesting security problem: Any code written with the assumption that magic quotes was running becomes a security hole when magic quotes is off.
So, Magic Quotes created an interesting example in which a well intentioned security mechanism made programs less secure.
mysql_query('SELECT * FROM PageData WHERE id = '.$id);
$id contains the variable in the URL string. If the id is 5, PHP sends the SQL command "SELECT * FROM PageData WHERE id = 5" to the database. Since one is sending straight text to mysql, hackers have learned that they can often inject SQL code into PHP strings. For example one might call the page.php with the command ("page.php?id=5; 'SELECT password FROM SecurityTable WHERE user=1').
The variable $id now contains the string "5; 'SELECT password FROM SecurityTable WHERE user=1'". The command in mysql_query() is now sending two SQL commands to the database engine.
When looking at logs for a web site; you will occasionally find hackers sending commands to pages to inject SQL strings into PHP pages. Hackers will even run scripts that systematically attack every variable sent to a page to see if it was properly validates. This type of attack is called an injection script.
The key to this sql injection script is the single quote character "'" which breaks out of one sql command and starts another.
To prevent injection scripts, programmers must validate all input from the web. Validating a string involves changing the quote character into something that won't be wrongly interpretted by SQL. PHP created a program called addslashes(). addslashes() escapes quotes with a slash. addslashes() translates "'" into "\'" which the database correctly interprets as a quote and not a break in a SQL statement.
Early PHP manuals instructed programmers to run addslashes() on all code from the web.
But even one sloppy piece of code in a large program created a security hole.
Tired of being hacked Webhosts came up with the clever idea called "Magic Quotes"
Magic quotes automatically runs addslashes() on all data coming into the web site. There were two big mistakes in this decision.
The first was that addslashes() escapes slashes. If you add slashes on the same data twice, you start getting extra slashes. the command addslashes("'") returns "\'". addslashes(addslashes("'")) returns "\\\'". Running the program recursively three times returns "\\\\\\\'"
This is actually an interesting application of the reflective paradox.
All of the code written to PHP best practices prior to MagicQuotes started returning multiple slashes. Programmers had to convert their code to addslashes(stripslashes(data)).
The second major flaw of Magic Quotes is that people around the world want to write programs in their native language using their native character sets.
Different character sets around the world use different delimiters for text. addslashes() and Magic Quotes assumes everything was written in a latin based character set. Different character sets use different delimiters.
One does not know what characters need to be escaped until after establishing the connection to the database. Each database has its own preferred mechanism for validating data. MySQL offers an awkward function called mysql_real_escape_string().
Magic Quotes turned out be a fiasco. Programmers who've written their own validation procedures want the feature off. A small number of programs have grown dependent on it.
Now here is the interesting security problem: Any code written with the assumption that magic quotes was running becomes a security hole when magic quotes is off.
So, Magic Quotes created an interesting example in which a well intentioned security mechanism made programs less secure.
Saturday, February 05, 2011
Health Care and the States
For decades, the fifty states have used health care regulations to rob their citizens blind.
The reason that Obamacare seems so much worse than local state regulations is that Obamacare got media attention. In contrast, state legislators have learned to sneak bad regulations past the public with essentially no scrutiny.
The proponents of nullification and states rights have two fatal flaws. The first flaw is that states don't have rights. Rights come from God. The Constitution states that people have rights, states and the federal government have limited powers. "States Rights" was the cry of slaveholders and Jim Crow.
Nullification is a different thing. Nullification states that a unconstitutional law cannot be law, so the states don't have to enforce it.
The bigger fatal flaw is that state regulation of health care is awful.
Every state has laws which block access and centralize health care into just a few politically connected hand.
Our health care rates go up every year because our individual state legislatures are cesspools of corruption. Unfortunately, people do not pay attention to their state legislatures and they get away with their skullduggery.
State regulation of health care is so bad that the horrible bill passed by the 111th Congress, as bad as it is, might actually do better than what the states have done to health care these past fifty years.
For Republicans to overturn Obamacare, they must come up with something more substantive then "states rights." Repealing Obamacare with the call for states rights will actually do little more than accelerate the corruption of state regulators and decrease the quality of care.
The reason that Obamacare seems so much worse than local state regulations is that Obamacare got media attention. In contrast, state legislators have learned to sneak bad regulations past the public with essentially no scrutiny.
The proponents of nullification and states rights have two fatal flaws. The first flaw is that states don't have rights. Rights come from God. The Constitution states that people have rights, states and the federal government have limited powers. "States Rights" was the cry of slaveholders and Jim Crow.
Nullification is a different thing. Nullification states that a unconstitutional law cannot be law, so the states don't have to enforce it.
The bigger fatal flaw is that state regulation of health care is awful.
Every state has laws which block access and centralize health care into just a few politically connected hand.
Our health care rates go up every year because our individual state legislatures are cesspools of corruption. Unfortunately, people do not pay attention to their state legislatures and they get away with their skullduggery.
State regulation of health care is so bad that the horrible bill passed by the 111th Congress, as bad as it is, might actually do better than what the states have done to health care these past fifty years.
For Republicans to overturn Obamacare, they must come up with something more substantive then "states rights." Repealing Obamacare with the call for states rights will actually do little more than accelerate the corruption of state regulators and decrease the quality of care.
Subscribe to:
Posts (Atom)