So, members of my website can post topics, replies, comments, edit them and so on. I always use htmlspecialchars
and addslashes
for html inputs to protect my site against XSS and SQL injection attacks. Is it enough or is there something more I miss?
Thanks.
问题:
回答1:
There is a lot that can go wrong with a web application. Other than XSS and SQLi, there is:
- CSRF - Cross Site Request Forgery
- LFI/RFI - Local File Include/Remote File Include caused by
include()
,require()
... - CRLF injection in
mail()
- Global Variable Namespace Poising commonly caused by
register_globals
,extract()
,import_request_variables()
- Directory Traversal:
fopen()
,file_get_contents()
,file_put_conents()
- Remote Code Execution with
eval()
orpreg_replace()
with/e
- Remote Code Execution with
passthru()
,exec()
,system()
and ``
There is a whole family of vulnerabilities regarding Broken Authentication and Session Management which is apart of the OWASP Top 10 that every web app programmer must read.
A Study In Scarlet is a good black paper that goes over many of these vulnerabilities that I have listed.
However, there are also strange vulnerabilities like this one in Wordpress. The definitive authority on what is a vulnerability is the CWE system which classifies HUNDREDS of vulnerabilities, many of which can affect web applications.
回答2:
You should use prepared statements (see PDO) to prevent SQL injection. When outputting the content htmlspecialchars() seems sufficient to prevent XSS.
Also take a look at these links for more ways to protect your site:
http://phpsec.org/projects/guide/
http://cwe.mitre.org/top25/#Listing
http://www.owasp.org/index.php/Top_10_2010-Main
回答3:
A better approach to protect against SQL injection is to use the escape
function specifically written for each database - for example, for PostGreSQL use pg_escape_string to escape string fields before inserting them in to the database. Or in your case, use mysql_real_escape_string
.
回答4:
You should use mysql_real_escape_string() for SQL, not addslashes. (Assuming you are using MySQL)
回答5:
When inserting data into database, use prepared statements. PDO are better than mysql_real_espace_string.
When displaying data, such as comments, posts, use htmlentities.
回答6:
SQL injection:
No addslashes nor mysql_real_escape_string could help alone. But only when used according some rules. And even then it's not enough. So, that's why prepared statements are way better for newbies - it require no thinking.
Both escaping and prepared statements can help with data only. For the operators/identifiers there are distinct rules. (Not a big deal though - every possible combination must be hardcoded in the script)
XSS:
Do not allow users to use HTML.
To prevent this, both strip_tags()
(with no allowed tags) or htmlspecialchars()
can be used.
If you want to allow some markup, consider a BB-code use.
CSRF:
Any significant form must contain an unique token, which should be compared to one, saved in the session.