6

I think hackers (or script kiddies) attacked my website using leaks of website's codebase. Posts in the database changed so that they contain this html:

<meta http-equiv="refresh" content="0;url=http://example.com"/>

But i can't rewrite the system now. What are the strategies to prevent this situation happening in the future?

I'm thinking of migrating admin script to a subdomain that allows access to certain domains. Or using mod_security SecFilterScanPOST and scanning all post request containing http-equiv etc. Or only allowing post requests from my server or all of them?

Thank you.

fatihpense
  • 618
  • 9
  • 11
  • 2
    Best solution, sanitize your data. Also you might want to investigate further in case they compromised the server itself which would be more of an issue than trying to prevent what they have already done. – kittycat Feb 15 '13 at 08:33
  • 6
    Security isn't an outer wrapper. If your core app has security holes, you need to secure it by fixing those holes. Not by plastering a bandaid on the outside. – deceze Feb 15 '13 at 08:34
  • 1
    @deceze as true as that is, it's not always an option in the real world – Sprague Feb 15 '13 at 08:39
  • 1
    @Sprague That sure sounds like a real world excuse. – Ja͢ck Feb 15 '13 at 10:08
  • 1
    @Jack lets not be naive here. The asker already stated that a rewrite was not an option. I also stated that I agree with deceze on the merits of his logic... but his comment doesn't move towards answering the question, it attempts to avoid asking it. – Sprague Feb 15 '13 at 14:16
  • @Sprague that's why this is the comment section, the answers go somewhere else :) – Ja͢ck Feb 15 '13 at 14:19
  • @deceze Actually if i could find those script kiddies, i would solve problem at its core :) Thank you all for comments and ideas... – fatihpense Feb 15 '13 at 18:45
  • As written in other posts already, do not use `http-equiv="refresh" `. Timed refresh must not exist as it would have a critical impact on users. This would breach Guidelines: WCAG 2.1 (A), WCAG 2.0 (AA), and it will be marked as error by major web browsers today. Use javascript instead. You can read more here: https://dequeuniversity.com/rules/axe/4.4/meta-refresh – Goemon Code May 19 '23 at 17:50

3 Answers3

3

The first step may be investigating where is the code is injected, which may help you to identify what the root clause is -

  1. If your web site get contents from database and the injected tag is retrieved as part of database content, probably your site has SQL injection flaw or other vulnerabilities that allow attackers to change the content there.

  2. If the tag in every PHP files, it means the attacker has access to your file system. Either he has access to your FTP or telnet or any other admin consoles, or your web site has vulnerabilities that allow attackers to modify/create files on the web site.

  3. It may also be possible for your server to have vulnerabilities that allow such access from the attackers.

After you identified the root cause, fix it accordingly =)

Here are some generic advises to help preventing the same from happening again:

  1. Review your web sites and server for vulnerabilities, either through code review, pen test or some automatic scans and fix them accordingly.

  2. Install update, hotfix, security patches promptly. Keep it updated, updated, updated, updated...

  3. Assign proper folder permissions (read-write, read-only, no access) on the file systems and grant only necessary rights to users (min-privilege principle).

    • For example, you may consider making the web server user only readable to all web content folder except upload folders.
    • Configuration files usually don't require to be writable by the web server user. Normally they are writable by administrator only. Also be careful not to allow the content of such files be accessible via the web server (i.e. via the http:// url of your web server). Putting them outside the web content root direct is a nice idea
    • Putting any upload folders outside the web content root directory is also a nice idea
    • Mine the owner of the files too, because owners can freely change the permission of the file.
  4. Be cautious when using 3rd-party components (e.g. Wordpress/Joomla plugins). Only use if you trust the publisher. Download only from main site. Remember to keep them up-to-dated too. Disable and remove them if necessary

  5. Restrict access to administrative consoles and services like FTP, Telnet, database administration consoles (e.g. phpMyAdmin) and etc. Assign good passwords for them. Best is don't let anyone except authorized to access it (e.g. using IP restrictions set in Firewall or configurations, or hide it behind VPN)

    • Actually you should avoid any clear text protocols when passwords (especially administrator's) are transmitted. There are usually a encrypted alternatives for them, e.g. Telnet -> SSH, FTP -> SFTP/FTP, HTTP/HTTPS.
    • Database port should really be avoided to be accessible from Internet. There is only rare screnario that you will need this. Configure it to listen on the loop-back interface in most case...
Balaji Kandasamy
  • 4,446
  • 10
  • 40
  • 58
circle
  • 122
  • 4
  • What does inserting HTML into a database have to do with SQL injection? You can do this with perfectly save prepared statements, too... – Francois Bourgeois Feb 15 '13 at 14:37
  • @circle Thank you for this long and useful answer. I will keep it and give it to my future children :) I think security is a checklist issue. Like a pilot, you should check everything without relying human memory... – fatihpense Feb 15 '13 at 18:52
  • @FrancoisBourgeois Yes prepared statements is an effective measure to SQL injections. And you are right that SQL injection is not the only way to insert HTML content into page if database is involved in generating the page content. It is also possible to use stored XSS or similar to achieve this too. I named SQLi here just because it has been very common for worms to make use of known SQLi in many CMS (e.g. Joomla) to insert malicious page header. – circle Feb 17 '13 at 12:26
2

See OWASP on both XSS and input validation.

Do not sanitize your input - you want the original <meta http-equiv="refresh" content="0;url=http://example.com"/> in your database - but instead treat it as untrusted data and escape/disarm it when it comes to output.

Francois Bourgeois
  • 3,650
  • 5
  • 30
  • 41
1

This is a lazy solution if you do not want to escape your data while reading from db (which you should).

function escape_deep(&$value)
{
 $value = htmlspecialchars($value);
}

array_walk_recursive($_GET, 'escape_deep');
array_walk_recursive($_POST, 'escape_deep');
Niclas Larsson
  • 1,317
  • 8
  • 13