- Server should use a deterministic method to timeout sessions. cron jobs are good. These should be lightening fast. See other posts in this blog. These timeouts address the situation where the user closes the browser and walks away without logging out.
- Logging out should force session cleanup. If temporary files are not security risks they can be removed by a different cron job.
- Temporary file cleanup can be performed less frequently, unless this would compromise sensitive data. cron jobs are good.
- AJAX controls may fail to execute properly if authentication is required for delivery. Pinging the server to check for session timeouts can limit user frustration when a page doesn’t function due to a session timeout. It may be difficult or prohibitive to attach error trapping to all the AJAX controls in an application. Another options is to cache the control content, but that may be impossible if it is truly dynamic.
- Ping requests may update the session file timestamp. A ping count can be used on the server side to differentiate between ping requests and user-initiated requests. After a certain number of ping requests, the server can time out the session. AJAX and page (HTML) user-initiated requests should clear the ping count.
- Users should be alerted gracefully of timeouts.
Category: "Web Applications"
Each step ends with place in version control, submit for review, evaluate review responses and apply them as appropriate..
- Define the page architecture, common page elements first. These must be stable before beginning.
- Build page level XHTML/CSS for all pages, target browser FireFox, with only enough back end code to deliver the pages. Use static server-side content to populate dynamic controls/queries for illustration. Create data in the database to support it. Validate the XHTML/CSS as well as possible (some libraries have proprietary attributes).
- If common components are identified in the previous step, they should be constructed reusable/shared components. For example, a file upload or search results dialog box will probably be used in more than one place. Both client and server-side code should address this to avoid duplicate code.
- Tune colors.
- Define and implement client-side functionality, allowing content to be delivered through AJAX, navigation, any dynamic operations.
- Implement client-side validation.
- Extend pages to run under any other browsers you will be supporting. Clearly indicate limitations, such as will function but may not display well. Provide notification for users of unsupported browsers.
- Integrate and implement server-side validation. It should be identical to client-side validation, with addition considerations for security.
- Implement page level functionality.
- Test, test, test.
Anyone writing web-based applications should refer to the above link and audit their code.
This is one of the best ways to improve the security of the application, and to learn how to write more secure applications in the future.
Never assume that your application can’t be attacked or compromised.
Although existing open source software on publicly accessible servers is easier for malicious users to attack and defeat, custom applications are not immune.
Reasons you should always strive to build secure applications:
- Improved security protects the data, the code, the server, the network the server is on, and your job. It limits the time wasted cleaning up after compromises.
- Quality. Security, done well, usually improves quality. It requires greater care to write the code.
- Future use of the code. Many applications start with a particular goal and grow. Soon they are distributed, and a wide audience can look at the code, either with an eye to collaborate - or attack.
Another excellent resource is http://phpsec.org, they have an audit you can run.
Don’t discount vulnerabilities with ‘that threat would not apply.’ Assume all threats will apply, because, in all likelihood, if they don’t at launch time, they will in the future.
Invest in SSL/HTTPS at the beginning and learn about Web Application Firewalls like mod_security (http://mod_security.org). It is okay to use a self-signed certificate, instruct affected users to trust it, with instructions on how to verify it (a screenshot is good).
Most importantly, take the time to read and learn. Even if you can’t address every issue as well as you would like, strive to address as many as possible. Loop back to improve the code if you have time.
“Together Everyone Achieves More”
- It is very difficult to test a complex RIA thoroughly. It is even more difficult if it is yours. Sending the system to the users, and asking them to focus on specific areas is an excellent way to find problems you missed. Remaining focused on delivering quality software and doing a good job makes it easier to acknowledge oversights, errors, bugs, and mistakes - and fix them.
- Don’t send harsh comments or accusations. If something is wrong, check very carefully to see what is happening. Report only the facts, for example: ‘this is in the log’, ‘this sequence of steps causes an error’. Read carefully. Take your time.
- Don’t underestimate the value of the data in the system. Take great care to protect it at all times from corruption. Test the system on a different server or using a different database prior to launch.
- Respect the value of other people’s time. Don’t ask them to test anything that you aren’t very confident in. Request their help with several, specific issues, to reduce communication overhead. Offer to meet them in person if it is difficult to resolve through email.
- Use version control. Be sure that if you changed the file last, you didn’t overwrite anyone else’s changes.
- Thank those that test the code and take the time to respond, even if they find problems.
- Even if there isn’t a problem, or it is a simple piece of code, it is good to allow others to review it and suggest changes. Whenever possible, make the changes.
- Avoid scope creep by adhering to written and recorded content. email and verbal changes that have been agreed upon should be entered into a defect management system. This ensures the details aren’t forgotten and also serves to limit the scope of changes when the work is done. Use the ids from the defect system to be sure everyone knows which issue is being addressed.
- Use neutral colors and be courteous in email replies. Many people perceive red text and UPPERCASE as harsh, even if the content isn’t. Blue, green, purple are better choices.
- Remember that it isn’t ‘your’ code, it belongs the the company or the client, whoever is paying your salary. The objective of the project isn’t to produce software, it is to provide a solution to a need or requirement. Strive to find the best solution.
- Give credit for good ideas from others.
- Test plans are excellent resources. They don’t need a specific template. Any way that you can comfortably explain what to do, and what should happen is find.
Notes on using a dojo/RIA web interface to launch background (server-side) scripts.
- File uploads can run under FF and IE with dojo.io.iframe.send, and it is a nice interface. There is another post on this blog, with sample code.
- Synchronizing background server tasks with client launch and monitor requires the client to be able to identify script failure to execute, execute reporting whether the operation was successful or not.
- Two-phase, asynchronous execution can be made much more secure by storing the second-phase action on the server. Thus, if the first-phase executes correctly, no information is required from the client to continue the operation. All data submitted can be disregarded.
- Success or Error can be indicated with HTTP headers in cases where no data is required on the response.
- Client-side redirects can be used to transition to the next phase after a successful run of one phase.
- User should be alerted that scripts initiated through the web interface cannot be stopped (unless a mechanism is provided).
- User should be able to return to a previously initiated scripts and view the output.
- Background script output should be delivered to the initiator through an email. User should be able to suppress email.
- Background scripts should deliver output in text only.
- Server must be responsible for state management. Server must ensure background scripts do not collide with each other, or the data, and must provide an interface that allows the client to determine if administration should be readonly or prohibited when specific scripts are executing.
- Server must be responsible for scheduling resource intensive tasks to prevent service interruptions.
- An object is an excellent way to allow a single dialog box to submit data to different scripts without writing additional code. The object is then assigned to the AJAX content property.
- Server must have intelligence to adjust state of client, for example hiding informational messages after termination, enabling buttons to allow continuation, and providing alerts for errors.
- Initial error reporting can be limited to ‘Error’, a simple indication that something went wrong. After testing, common errors should be delivered with additional explanatory text.
- Break server side code into components such that only the code required to execute is read. This doesn’t always work out perfectly, and there are impacts to opening alot of files as well, but the server impacts are less serious than the client side, because there is no data transfer.
- Put some timing code into the application so you can see where the time goes. Use YSlow to improve page delivery performance.
- Use FireBug to monitor traffic between client and server.
- Use a log file to write out debugging information. Check the error_log frequently. Use echo, var_dump, and exit. Build graceful error reporting into the application from the beginning. This will make debugging much easier. Log all errors. Put a switch in to allow debug displays to be suppressed for production systems.
- Use a tee (*nix command) to pipe script output to a file and into mail.
- Document the entire process and describe it to the appropriate people. This will ensure you understand what is happening and that it is what is supposed to be done. Be ready to change.
- Write a good test plan and use it.
- Be mindful of security. Validate all inputs. Escape all command line parameters that are user submitted. Check for access privileges for all requests, at all times. Avoid divulging application details or data.
- Copy script output to a temporary access area, do not grant access further into the server for output display. Identify script output with the script name and session id.
- Have Apache execute as apache:apache, or nobody:nobody, and allow only those scripts that should be executed through the web to have execute permissions for that user.
- Be persistent and creative.