
Towards a secure web resource. Part 2 - Development
- Tutorial
I am glad to continue to tell my views on approaches to creating secure web resources and web applications and move on from the first part , which contains some generally useful security instructions for creating the infrastructure for the project, and the second, developing the application itself.
It is logical to start with them, with their knowledge and experience. The fault of the employee himself in that he does not have sufficient knowledge about security development is minimal. Primary responsibility is on leadership, HR and anyone else. The problem arises during the recruitment phase. Let's consider a typical interview, even based on the guides that were laid out here on Habré:
No one anywhere (including the last article in the comments) has ever mentioned the security aspects. "The fish rots from the head" and this is a fact. What do I suggest? When recruiting employees, first of all, to figure it out yourself though in the basic moments of programming, incl. security perspective and ask questions about them. And I propose the following questions, the answers to which (and most importantly - the detail of the explanation) will give at least some picture of the developer’s knowledge in the field of security. We will select some typical constructions and vulnerabilities in them:
We ask for an opinion. It doesn't matter if the supplicant knows whether this is stored or the DOM XSS. The main thing is that he understands that such constructions are unacceptable (and it will be cool if he knows the consequences of such constructions. And even cooler is the solution). The task can be complicated with the substitution of data through JS obtained from elsewhere.
This is a reference to one of my previous articles (the problem was not contrived, but was taken from practice). And so, we are looking for a specialist in Zend, he abruptly answers all questions, but ... It is quite normal for such designs. Or substitutes in where the array that came from GET / POST via implode.
Download image. People with at least some experience will immediately say that no one writes that way. $ _FILES ["file"] ["type"] is assigned a value from HTTP, which is easily "faked". Well, okay, the candidate says that we simply change to “file - ib” or use PEAR / Zend for this and deal with the end (at the same time, it refers to stackoverflow ). But here he will be wrong (but already better). It is quite easy to create an evil.php file containing php code, while having image headers. So here it is necessary to check the headers of an already accepted file (via `file`, PEAR or Zend, for example), and set the extension based on the mime-type defined.
I want to say that incorrect (inaccurate) answers should not be decisive when accepting an employee (this opinion is based on rational reasons, and not from a security point of view), but keep in mind that the employee needs to study certain material in this area. And the first time you need to check its code, especially at some important points (like downloading files).
And we have already accepted employees. We need to conduct separate work with them and periodically “give heat”, parsing any vulnerable code found at all. Or at least a mailing list with links to read on this topic.
And so, we are moving from the human factor to the technical one.
I'll start with the directory structure. It is practiced by many:
I use a similar directory structure, and I do not see any problems with it. Let's start with the last paragraph - htdocs. In htdocs we have only 1 php script - index.php (referring to the first part of the article), a kind of bootsrtap that starts the entire application and gives the necessary functionality depending on location. There is all the statics and upload from users. Only 1 file remains executable to php, and this is great!
app - application, rendered as htdocs, this eliminates such constructions in module files as unnecessary:
Direct access to files is basically impossible. Also, we don’t need to create a bunch of empty index.html in each folder if, for some unknown reason, we have indexing enabled in directories and we cannot disable it.
config.ini is also not accessible from the web, therefore it will not be given in plain-text by direct access to it.
Cron scripts (or scripts for jenkins) are also conveniently stored in the directory we need.
We will analyze the most popular scheme for using design patterns - MVC and decide where we have and what will be.
Validation A lot depends on what is accepted in your team. Usually, nevertheless, data validation is taken here when the model is initialized. But this can be successfully done elsewhere (service as an example).
Here I will consider the eternal question - where to convert HTML special characters? For example, phpbb does this when writing data to the database, and as a result, the data takes up more space. Message
And it can also lead to data validation order errors (which are present in phpbb).
My opinion is that data should be recorded in the form in which it came. And convert specials. characters on the output in the template engine.
Of course, direct conversion of specials. characters when writing to the database is safer than converting them to the output. Because in one place the developer did everything right, and in another place he forgot (or deduced by another developer). But the first option can be considered a crutch.
The main vulnerabilities are most often found in places with data manipulation. Here I want to repeat what I wrote about in my first articles, and suggest using the following construction:
Where errorLog () - will add an error record to the database, send an email to dev@example.com or something else. You will always be aware of all the problems that happen on the project. Also, if we use New Relic (which was mentioned in the first part of the article), then we get a similar beautiful monitoring: Screen with an example of logging an error when someone tried to pick up the phpmyadmin address, for example, using nikto Time, log , and the amount of occurrence of this error. error.log in the modern version.

If your product is updated by iterations, then the approach of security-checking the downloaded code on production easily fits into such a process organization. A full diff is made and viewed by experienced programmers or the security department (human).
Product development on the framework is not a panacea for security (RoR has especially confirmed this from the very beginning of the year). Using the most popular engines and making full use of their API when developing modules is also not a panacea ( WordPress => 3.5 XMLRPC pingback additional issues ).
My opinion remains the same, that it is better to write all the code from scratch, while already having experience in security (and preferably in hacking / pentest). But, of course, this is practically inappropriate in the modern world, since it requires quite large additional costs for the business (and finding so many specialists at once is quite difficult).
By the way, I have an excellent schedule on this subject (which I learned from Alexey Babenko from Information Protection, who, in turn, found out about him at one of the overseas internships on security) An

optimal level of security at minimal cost. The picture is found here.
From which we can conclude that the initial investment gives a quick and sharp jump in security. But the larger the investment, the less risk will be reduced.
Series:
The security hole has not been fixed as product managers want a new feature

Programmers
It is logical to start with them, with their knowledge and experience. The fault of the employee himself in that he does not have sufficient knowledge about security development is minimal. Primary responsibility is on leadership, HR and anyone else. The problem arises during the recruitment phase. Let's consider a typical interview, even based on the guides that were laid out here on Habré:
- PHP Developer Interviews - Rank 54
- Candidates with declared status of “PHP expert” and questions on logic - rating 46, there is also an interview plan
- Interview Today - rating 68
- The perfect job interview? - rating 71, discussion of the “perfect” interview
No one anywhere (including the last article in the comments) has ever mentioned the security aspects. "The fish rots from the head" and this is a fact. What do I suggest? When recruiting employees, first of all, to figure it out yourself though in the basic moments of programming, incl. security perspective and ask questions about them. And I propose the following questions, the answers to which (and most importantly - the detail of the explanation) will give at least some picture of the developer’s knowledge in the field of security. We will select some typical constructions and vulnerabilities in them:
Xss
$name!";
?>
We ask for an opinion. It doesn't matter if the supplicant knows whether this is stored or the DOM XSS. The main thing is that he understands that such constructions are unacceptable (and it will be cool if he knows the consequences of such constructions. And even cooler is the solution). The task can be complicated with the substitution of data through JS obtained from elsewhere.
Sqli
where($value);
?>
This is a reference to one of my previous articles (the problem was not contrived, but was taken from practice). And so, we are looking for a specialist in Zend, he abruptly answers all questions, but ... It is quite normal for such designs. Or substitutes in where the array that came from GET / POST via implode.
File upload
Download image. People with at least some experience will immediately say that no one writes that way. $ _FILES ["file"] ["type"] is assigned a value from HTTP, which is easily "faked". Well, okay, the candidate says that we simply change to “file - ib” or use PEAR / Zend for this and deal with the end (at the same time, it refers to stackoverflow ). But here he will be wrong (but already better). It is quite easy to create an evil.php file containing php code, while having image headers. So here it is necessary to check the headers of an already accepted file (via `file`, PEAR or Zend, for example), and set the extension based on the mime-type defined.
I want to say that incorrect (inaccurate) answers should not be decisive when accepting an employee (this opinion is based on rational reasons, and not from a security point of view), but keep in mind that the employee needs to study certain material in this area. And the first time you need to check its code, especially at some important points (like downloading files).
And we have already accepted employees. We need to conduct separate work with them and periodically “give heat”, parsing any vulnerable code found at all. Or at least a mailing list with links to read on this topic.
And so, we are moving from the human factor to the technical one.
Hierarchy
I'll start with the directory structure. It is practiced by many:
example.com
├── app
│ ├── config.ini
│ ├── framework
│ └── src
│ ├── controller
│ ├── model
│ └── view
├── crontab
│ ├── daily_flush_stat.php
│ └── weekly_remove_cache.sh
└── htdocs
├── css
├── img
├── index.php
└── js
I use a similar directory structure, and I do not see any problems with it. Let's start with the last paragraph - htdocs. In htdocs we have only 1 php script - index.php (referring to the first part of the article), a kind of bootsrtap that starts the entire application and gives the necessary functionality depending on location. There is all the statics and upload from users. Only 1 file remains executable to php, and this is great!
app - application, rendered as htdocs, this eliminates such constructions in module files as unnecessary:
if (!defined('IN_SITE')) die ("Hack attempt!");
Direct access to files is basically impossible. Also, we don’t need to create a bunch of empty index.html in each folder if, for some unknown reason, we have indexing enabled in directories and we cannot disable it.
config.ini is also not accessible from the web, therefore it will not be given in plain-text by direct access to it.
Cron scripts (or scripts for jenkins) are also conveniently stored in the directory we need.
Application code
We will analyze the most popular scheme for using design patterns - MVC and decide where we have and what will be.
Model
Validation A lot depends on what is accepted in your team. Usually, nevertheless, data validation is taken here when the model is initialized. But this can be successfully done elsewhere (service as an example).
View
Here I will consider the eternal question - where to convert HTML special characters? For example, phpbb does this when writing data to the database, and as a result, the data takes up more space. Message
WOW >>> "NEW NEW NEW"
It will not take 42 bytes (in UTF8), but 82, as it will look like WOW >>> "NEW NEW NEW"
And it can also lead to data validation order errors (which are present in phpbb).
My opinion is that data should be recorded in the form in which it came. And convert specials. characters on the output in the template engine.
Of course, direct conversion of specials. characters when writing to the database is safer than converting them to the output. Because in one place the developer did everything right, and in another place he forgot (or deduced by another developer). But the first option can be considered a crutch.
Controller
The main vulnerabilities are most often found in places with data manipulation. Here I want to repeat what I wrote about in my first articles, and suggest using the following construction:
try {
// try something
} catch (Exception $e) {
echo "Сожалеем, но произошла ошибка. Разработчики уже уведомлены и в скором времени все исправят!"
errorLog($e->getMessage());
}
Where errorLog () - will add an error record to the database, send an email to dev@example.com or something else. You will always be aware of all the problems that happen on the project. Also, if we use New Relic (which was mentioned in the first part of the article), then we get a similar beautiful monitoring: Screen with an example of logging an error when someone tried to pick up the phpmyadmin address, for example, using nikto Time, log , and the amount of occurrence of this error. error.log in the modern version.

Iterations
If your product is updated by iterations, then the approach of security-checking the downloaded code on production easily fits into such a process organization. A full diff is made and viewed by experienced programmers or the security department (human).
Framework, CMS / CMF
Product development on the framework is not a panacea for security (RoR has especially confirmed this from the very beginning of the year). Using the most popular engines and making full use of their API when developing modules is also not a panacea ( WordPress => 3.5 XMLRPC pingback additional issues ).
Conclusions?
My opinion remains the same, that it is better to write all the code from scratch, while already having experience in security (and preferably in hacking / pentest). But, of course, this is practically inappropriate in the modern world, since it requires quite large additional costs for the business (and finding so many specialists at once is quite difficult).
By the way, I have an excellent schedule on this subject (which I learned from Alexey Babenko from Information Protection, who, in turn, found out about him at one of the overseas internships on security) An

optimal level of security at minimal cost. The picture is found here.
From which we can conclude that the initial investment gives a quick and sharp jump in security. But the larger the investment, the less risk will be reduced.