6 ms·
WordPress security plugin Hide My WP addresses SQL injection, deactivation flaws
- perrohunter 5y agoIronic
- angrygoat 5y agoSQL injection draws attention to the fact that almost all web applications run as root, in regards to the most important asset: the data. It’s odd that this hasn’t got more attention. It should be easier to write backends that tie data access more closely to user credentials without the backend trying to enforce that itself. Is there anything out there that makes this easy to do?
- Hendrikto 5y ago> almost all web applications run as root That‘s largely a configuration problem. They don‘t have to run as root, most of the time.
- eloff 5y agoWith regards to the database. Not UNIX root.
- eliaspro 5y agoShould there ever be a web application that needs to run as root, it should be rewritten. All logic requiring root privileges should be moved into a separate system service with a minimal attack surface to which the web application delegates those special tasks.
- vntok 5y agoYou misunderstood the grandparent's comment and replied to a confused parent. The application does not need to run as root, however even when it runs as a normal user, it generally has full read/write access to the application database. Which is a problem that is not easily solvable.
- raxxorrax 5y agoI think you need root permissions to start a network service on port 80 on Windows. There is a security risk here which was addressed in a fairly recent Chrome release that local addresses need a respective CORS rule. At least I believe so. Disadvantage with the Windows behavior is that a webservice running on said port has elevated permissions and if you surf the web with the same machine, a script inserted into a site could launch attacks against it. Of course the site itself could be malicious, in that case the CORS rule wouldn't do much. Of course you are correct, running directly on port 80 might just be a bad idea, but for development purposes I might do that.
- Vogtinator 5y agoPorts < 1024 are defined as "privileged", so it's not just a Windows thing. What usually happens is that the process only has the necessary capability for a brief period to open the port and drops it immediately before processing any requests.
- iso1631 5y agoIt was poorly phrased, but the OP meant that web apps usually have full unrestricted access to the database. Clearly that's not entirely true (your webapp likely doesn't need truncate, or the ability to add/change stored procedures, or the schema) but it's broadly there. Your database is effectively chmod o+r
- kenniskrag 5y agoThere is row level security. But that usually means many db users or sometimes usergroups are supported. https://www.postgresql.org/docs/current/ddl-rowsecurity.html https://www.postgresql.org/docs/current/ddl-rowsecurity.html
- tremon 5y agoThere isn't, at least not really, since webapps are designed as full-service kiosks: all of the data management, user management and access control are supposed to be handled from the same console. If you want the database to enforce access controls, then every user must exist as a separate entity in the database, which is good, but then the webapp also needs the permissions to manage user accounts in the database, which is bad for security, and the webapp can no longer use connection pooling, which is bad for performance. There are tricks you can use, such as implementing row-level security and tying it to some concept of end user identity, but even ignoring that ORM's don't understand or support RLS and developers therefore won't use it: it's still the same problem of letting the fox guard the henhouse. The webapp is the single control point for both user access and user administration (including self-service account creation and password reset), so whatever solution you come up with, the webapp will need to have super-user access to do that, and therefore if the webapp is compromised, your data-level access controls can be compromised too. So, in order to even begin thinking about securing your data, the webapp should probably be split into multiple reduced-access microservices that handle different aspects of the webapp function. As long as we're talking about a single monolithic backend, any attempt at scope mitigation can (and likely will) be defeated.
- konha 5y agoThere are some easy wins most applications could use but don‘t most of the time. Like having sensible permissions for your app-db-user. Running migrations in a separate process? No need to have permission to do schema changes. Events are only written to the db and not queried/viewed from the app itself? Grant only INSERT rights to the table etc.
- formerly_proven 5y agoIt's not that we don't know how to build things securely, it's just that we routinely ignore even basic principles of security 'cause it's easier. Virtually every webapp violates complete mediation and so it's just unreasonable to expect security. Similarly, most developers don't care for security and even less about principles and system design. Again, it's unreasonable to expect secure outcomes from that.
- friendzis 5y agoIf your database supports session wide environment variables you can attach user/group/permissions object to the session and have your queries/functions/procedures check that. If your database supports writable views (e.g. via triggers) you can build parametric views. Both are not plug-and-play modules in your framework and requires actual DBA, though.
- cm2187 5y agoI always wondered, how do they exfiltrate the data? The website isn’t designed to display any schema. Do they save it as file from the SQL server? Can’t that be locked down? The attacker would still be able to delete but at least not extract.
- bflesch 5y agoIf you're able to inject SQL, and the return value of the SQL query is not directly displayed to the user, you may use a timing-based side channel to exfiltrate data. E.g. in order to exfiltrate the string "Test123" you would go character-by-character, starting with the first character "T". For each ASCII character you would wait 10ms, as "T" is ASCII #84 [1] you'd sleep() for 84*10=840ms. This sleep() can be measured from the attacker side because the SQL query will block the HTTP response. This way, without "seeing" a result, the attacker is able to return data. [1] https://en.m.wikipedia.org/wiki/File:ASCII-Table-wide.svg https://en.m.wikipedia.org/wiki/File:ASCII-Table-wide.svg
- Ginden 5y agoWe're there any actual timings attacks executed like this? I'm talking about stack "attacker => internet => reverse-proxy => app => database", not extracting data over LAN from exposed app.
- bflesch 5y agoYes, that's one way to extract data by (ab)using a blind sql injection vulnerability. If you look at sqlmap [1], they offer two techniques for blind sql injection: boolean-based and time-based. Boolean-based should be used when the app just returns an error page (or not) based on your sql injection. The time-based approach should be used when no error page appears but the SQL is still executed. But when I look at sqlmap docs for the time-based approach [2] I think I got the initial explanation wrong. It will do a 5 second delay if a certain condition is met, e.g. "Is the first character of the value an 'T'? If yes, wait 5 seconds; if not, return immediately". And then send hundreds of requests in parallel to iterate over all positions & possible characters. [1] https://github.com/sqlmapproject/sqlmap/wiki/Usage#sql-injection-techniques-to-test-for https://github.com/sqlmapproject/sqlmap/wiki/Usage#sql-injec... [2] https://github.com/sqlmapproject/sqlmap/wiki/Usage#seconds-to-delay-the-dbms-response-for-time-based-blind-sql-injection https://github.com/sqlmapproject/sqlmap/wiki/Usage#seconds-t...
- ozim 5y agoSQL injections for me are solved problem. Frameworks and ORMs are making it easier on back-ends to tie data access to user credentials. The same with multi-tenancy if you use good framework with ORM you have all the tools to do filtering on higher level of abstraction. The same with referential consistency on database if it is there - ORM will help you to load data that is tied to that account. Making user like web app users on database level would make all development/ops really costly. If someone is writing SQL queries directly, he has to have a good reason for it. Like if it is plugin for Wordpress it probably is not that easy to use ORM.
- Hendrikto 5y ago> “The function hmwp_get_user_ip tries to retrieve the IP address from multiple headers, including IP address headers which can be spoofed by the user such as X-Forwarded-For,” reads a blog post published by Jong yesterday (November 24). ”By supplying a malicious payload in one of these IP address headers, it will be directly inserted into the SQL query which makes SQL injection possible.” > wpWave [adressed] both flaws in Hide My WP version 6.2.4, released on October 26.
- deleted 5y ago[deleted]
- zekica 5y agoWP can't fix this entire class of vulnerabilities properly or it won't be Wordpress any more. It is unfortunate that Wordpress is one of the worse options for making websites today (not WP itself, but any theme or plugin can easily be coded to have SQLi), yet it is the most popular.
- Lendal 5y agoNot surprising to me. I work at a small company, focused on industrial automation. It can be very expensive and time-consuming to automate things, so our internal processes are ironically manual. Customers don't pay us to automate our internal processes, so that never gets done.
- cm2187 5y agoBut it doesn’t cost more to use a parametrised query. That’s dev incompetence not cost pressure.
- rmbyrro 5y agoI'm not familiar with WP under the hood. Am I being naive or is it feasible to write a routine that scans plug-ins source code looking for insecure query argument handling?
- masklinn 5y agosemgrep has php support, so it should be possible, at least with respect to the “basic” APIs. If a plugin wraps the raw sql apis I don’t think semgrep can “inline” the information, so you’d have to reach for the taint tracking but that’s way more complicated than just check rules.
- withinboredom 5y agoThere’s a couple of excellent static analysis tools (phpstan, psalm) that can catch this kind of stuff. I’m 99% sure that psalm’s security suite would catch this.
- rmbyrro 5y agoWeird - or, oddly, not surprising - that no one seems to be using these tools
- ChrisMarshallNY 5y agoThis is one of those types of things that shouldn’t happen anymore, but does. I’m pretty sure that WordPress now has their own low-level version of PDO Prepared Statements. Also, they have a lot of even higher-level DB abstractions. I can’t think of any reason to directly access the DB from a plugin or theme.
- madsohm 5y ago> I can’t think of any reason to directly access the DB from a plugin or theme. Because it's PHP and it's easy.
- ChrisMarshallNY 5y agoToo true. It’s not PHP’s fault, though. The same type of argument is applied to C++. We keep developing “nerf-world” languages, designed to protect ourselves from ourselves, and most fall down before they get a chance to even get going; mostly because they constrain, without empowering. I remember moving to Pascal, after using Assembly and Machine Code. It was very frustrating for me. Pascal was one of the earliest “safe” languages. The problem is that we can’t build houses, using PlaySkool “Li’l Builder” toolsets. Also, the WP Codex is really disorganized. It’s difficult to find anything in it, and that is deadly. Geeks like to design clever architectures, but we hate to document them.
- tyingq 5y ago>I’m pretty sure that WordPress now has their own low-level version of PDO Prepared Statements. I imagine it's well tested, but it's a bunch of PHP escaping and regexes inside of wp-db.php. It is not at all real placeholders and prepared statements, though the functions are named that way. I suppose because there's too much tech debt to use normal placeholders.
- ChrisMarshallNY 5y agoAh ... well, it's better than nothing. For me, I always use PDO, and prepared statements and transactions. I get a lot of power, for free. I'm not a particularly good DB programmer, so I need all the help I can get.
- virgilp 5y agoNewrelic synthetic check cannot be used to verify that newrelic site is functional(their synthetic checks use Chrome 72, their site understandably doesn't support such old browsers) There's a saying here that the shoemaker's children walk barefoot. I think this might not be an isolated phenomenon
- simondotau 5y agoThis is ridiculous. SQLi is a dumb problem and any development environment worth using should make it trivial to avoid. All you have to do is never allow SQL queries to be formed using string concatenation. Or if you do, make sure you're excruciatingly strict about it. I run a large-ish web application written in ColdFusion (more precisely, CFML running on the open source Lucee) which is a language where string concatenation is happening all the time. This is a very old language which will look embarrassingly janky compared to any of the new hotness in vogue on Hacker News. But even in CFML I can trivially guarantee zero SQLi by parameterising all variables. Query parameters. They're a thing. If you don't know how your favourite programming language has implemented them, learn it. Use them.
- deleted 5y ago[deleted]
- asddubs 5y agoI agree of course, and in the case of the article you're absolutely right, although more generally there are edge cases where parameterization doesn't work, like giving choice of which row to order by. Naturally in such cases you should be operating on a whitelist of options and not pass the user input to the query, but the point is that some situations do still have to be accounted for.
- simondotau 5y agoI have no problem placing "if" or "switch" statements within the SQL in order to enable/disable various components of the query. The risk is when you're bringing in anything other than local constants. In the rare instances where I do this, I'm analysing the full scope of potential valid variables. I then make local copies of the variables which have been pummelled with the narrowest possible regular expression, e.g. slightly_safer = unsafe.replace(/[^0-9A-Za-z]/gi, '') Stripping away all punctuation eliminates most forms of SQLi.
- asddubs 5y agofor mysql at least, if you're dealing with table names you can just do a backtick escape, where you wrap the table/column name in backticks and escape any backticks within it with two backticks. That's usually my go-to in situations like this, in addition to a whitelist. anything else you can usually parameterize
- mmaunder 5y agoThis plugin has a low install count for WordPress at around 26K. It’s a commercial plugin as opposed to one of the plugins in the WP repo which helps explain the low install count. Most of the plugins that WP researchers look at are in the official repo with higher install counts, so it’s nice to see stuff like this get some code coverage among researchers. Envato should really invest in their own automated and human vulnerability research. I think there’s probably a lot of badness out there among the commercial plugins but in many cases researchers have to buy the plugin to take a look.
- patchstack 5y agoHere are full details of that vulnerability: https://patchstack.com/hide-my-wp-vulnerabilities-fixed/ https://patchstack.com/hide-my-wp-vulnerabilities-fixed/